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 it wont work). My problem is that don't want to exceed the maximum amount of physical memory i have on the machine, but as i understand i can't add such a constraint to the default memory cache.
In general the policy is:
- If the object has been in the cache for 10 min with no requests it is removed
- If a new object is added to the cache and the maximum amount of avaliable physical memory is close to used, elements are removed based on LRU
My cache can contain many different objects and they range from 10mb to 2-3gb, so i can't really get the trim
function to work.
Are there any suggestions on how to implement a LRU cache monitoring the ram usage? And hoppefully it can be done using the caches in .net?
Edit
I've added a simple example where the MemoryCache is limited to 100Mb and 20% of the physical memory, but that does not change anything. My memory is filled with no removal of cache entries. Note that the polling interval is changed to evert 5 second.
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());
}
}