awe*_*eis 5 c# caching memory-management lru
我正在尝试在我的应用程序中实现一些缓存,我想在C#中使用默认的内存缓存(如果此要求不起作用,则可以更改此要求)。我的问题是不想超过计算机上的最大物理内存量,但是据我了解,我无法将这样的约束添加到默认内存缓存中。
通常,该策略是:
我的缓存可以包含许多不同的对象,它们的范围从10mb到2-3gb,因此我无法真正使用该trim功能。
关于如何实现监视ram使用情况的LRU缓存有什么建议吗?希望可以使用.net中的缓存来完成?
编辑
我添加了一个简单的示例,其中MemoryCache限制为100Mb和物理内存的20%,但这不会改变任何内容。我的内存已满,无法删除缓存条目。请注意,轮询间隔更改为外翻5秒。
class Item
{
private List<Guid> data;
public Item(int capacity)
{
this.data = new List<Guid>(capacity);
for (var i = 0; i < capacity; i++)
data.Add(Guid.NewGuid());
}
}
class Program
{
static void Main(string[] args)
{
var cache = new MemoryCache(
"MyCache",
new NameValueCollection
{
{ "CacheMemoryLimitMegabytes", "100" },
{ "PhysicalMemoryLimitPercentage", "20" },
{ "PollingInterval", "00:00:05" }
});
for (var i = 0; i < 10000; i++)
{
var key = String.Format("key{0}", i);
Console.WriteLine("Add item: {0}", key);
cache.Set(key, new Item(1000000), new CacheItemPolicy() { UpdateCallback = UpdateHandler } );
}
Console.WriteLine("\nDone");
Console.ReadKey();
}
public static void UpdateHandler(CacheEntryUpdateArguments args)
{
Console.WriteLine("Remove: {0}, Reason: {1}", args.Key, args.RemovedReason.ToString());
}
}
Run Code Online (Sandbox Code Playgroud)
看起来System.Runtime.Caching.MemoryCache类非常适合这个要求。您为每个项目设置缓存策略,因此,如果您添加缓存策略为 SlidingExpiration 且 TimeSpan 为 10 分钟的项目,您应该会获得所需的行为。
这只是一个 .Net v4 类,因此它在早期运行时版本中不存在。如果您处于 Web 环境中,ASP.Net 缓存的行为类似,但可能不允许您管理系统信息。
您可以在创建缓存时设置缓存大小限制,使其不超过特定的内存占用量:
var myCache = new MemoryCache(
"MyCache",
new NameValueCollection { { "PhysicalMemoryLimit", "50" }} // set max mem pct
);
Run Code Online (Sandbox Code Playgroud)
这应该可以防止对磁盘进行任何分页,至少在您的应用程序中是这样。如果存在外部内存压力或系统过度积极地将内存分页到磁盘,您的缓存可能仍会被调出,但这不是由于应用程序内的过度使用。据我所知,C# 中没有办法保留内存页。