Default Cache with LRU Policy

I am trying to implement some caching in my application and I want to use the default memory cache in C # (this requirement can be changed if this does not work). My problem is that you do not want to exceed the maximum amount of physical memory that I have on the machine, but as far as I understand, I cannot add such a restriction to the default memory cache.

In general, the policy is as follows:

  • If the object was in the cache for 10 minutes without requests, it is deleted
  • If a new object is added to the cache and the maximum amount of available physical memory is close to use, elements are deleted based on LRU

My cache can contain many different objects, and they vary from 10 to 2-3 GB, so I can not get the trim function to work.

Are there any suggestions on how to implement the LRU cache controlling the use of the plunger? And by the way, can this be done using caches in .net?

Edit

I added a simple example where MemoryCache is limited to 100 MB and 20% of physical memory, but that does not change anything. My memory is full without deleting cache entries. Note that the polling interval changes to evert 5 seconds.

 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()); } } 
+4
source share
1 answer

It seems that the System.Runtime.Caching.MemoryCache class would be consistent with this score. You set a caching policy for each element, so if you add an element with a SlidingExpiration caching policy with TimeSpan in 10 minutes, you should get the behavior you are looking for.

This is only the .Net v4 class, so it does not exist in earlier versions. If you are in a network context, the ASP.Net cache behaves the same way, but it probably will not allow you to manage system information.

You can set limits on the size of the cache when it is created so that it does not exceed a certain amount of memory:

 var myCache = new MemoryCache( "MyCache", new NameValueCollection { { "PhysicalMemoryLimit", "50" }} // set max mem pct ); 

This should prevent any paging to disk, at least in your application. If there is excessive memory pressure or the system is too aggressive about paging memory to disk, your cache may be unloaded, but not because of excessive use in your application. As far as I know, there is no way to reserve memory pages in C #.

+4
source

Source: https://habr.com/ru/post/1400811/


All Articles