Кэш памяти по умолчанию с политикой LRU

Я пытаюсь реализовать кэширование в своем приложении и хочу использовать кеш памяти по умолчанию в C# (это требование можно изменить, если оно не будет работать). Моя проблема в том, что я не хочу превышать максимальный объем физической памяти, который у меня есть на машине, но, насколько я понимаю, я не могу добавить такое ограничение в кеш памяти по умолчанию.

В целом политика такова:

  1. Если объект находится в кэше в течение 10 минут без запросов, он удаляется
  2. Если в кэш добавляется новый объект и максимальное количество доступной физической памяти близко к используемому, элементы удаляются на основе LRU

Мой кеш может содержать много разных объектов, и они варьируются от 10 МБ до 2-3 ГБ, поэтому я не могу заставить работать функцию trim.

Есть ли предложения по реализации LRU-кэша, отслеживающего использование оперативной памяти? И, надеюсь, это можно сделать с помощью кешей в .net?

Редактировать

Я добавил простой пример, когда MemoryCache ограничен 100 Мб и 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());
    }
}
5
задан aweis 11 March 2012 в 20:32
поделиться