MemoryCache не подчиняется ограничениям памяти в конфигурации

Я работаю с классом .NET 4.0 MemoryCache в приложении и пытаюсь ограничить максимальный размер кеша, но в моих тестах не оказалось, что кеш фактически подчиняясь ограничениям.

Я использую настройки, которые согласно MSDN должны ограничивать размер кеша:

  1. CacheMemoryLimitMegabytes : максимальный размер памяти в мегабайтах, который является экземпляром объект может вырасти до. "
  2. PhysicalMemoryLimitPercentage : " Процент физической памяти, которую может использовать кэш, выраженный в виде целого числа от 1 до 100. Значение по умолчанию - ноль, что означает, что Экземпляры MemoryCache управляют своей собственной памятью 1 в зависимости от объема памяти, установленной на компьютере ». 1. Это не совсем правильно - любое значение ниже 4 является игнорируется и заменяется на 4.

Я понимаю, что эти значения являются приблизительными, а не жесткими ограничениями, поскольку поток, очищающий кеш, запускается каждые x секунд и также зависит от интервала опроса и других недокументированных переменных. Однако даже с учетом эти отклонения, я вижу совершенно несогласованные размеры кеша, когда первый элемент удаляется из кеша после установки CacheMemoryLimitMegabytes и PhysicalMemoryLimitPercentage вместе или по отдельности в тестовом приложении. Чтобы быть уверенным, я запускал каждый тест 10 раз и вычислял среднее значение.

Это результаты тестирования приведенного ниже примера кода на 32-битном ПК с Windows 7 с 3 ГБ ОЗУ. Размер кеша берется после первого вызова CacheItemRemoved () в каждом тесте. (Я знаю, что фактический размер кеша будет больше этого)

MemLimitMB    MemLimitPct     AVG Cache MB on first expiry    
   1            NA              84
   2            NA              84
   3            NA              84
   6            NA              84
  NA             1              84
  NA             4              84
  NA            10              84
  10            20              81
  10            30              81
  10            39              82
  10            40              79
  10            49              146
  10            50              152
  10            60              212
  10            70              332
  10            80              429
  10           100              535
 100            39              81
 500            39              79
 900            39              83
1900            39              84
 900            41              81
 900            46              84

 900            49              1.8 GB approx. in task manager no mem errros
 200            49              156
 100            49              153
2000            60              214
   5            60              78
   6            60              76
   7           100              82
  10           100              541

Вот тестовое приложение:

using System;
using System.Collections.Generic;
using System.Collections.Specialized;
using System.Linq;
using System.Runtime.Caching;
using System.Text;
namespace FinalCacheTest
{       
    internal class Cache
    {
        private Object Statlock = new object();
        private int ItemCount;
        private long size;
        private MemoryCache MemCache;
        private CacheItemPolicy CIPOL = new CacheItemPolicy();

        public Cache(long CacheSize)
        {
            CIPOL.RemovedCallback = new CacheEntryRemovedCallback(CacheItemRemoved);
            NameValueCollection CacheSettings = new NameValueCollection(3);
            CacheSettings.Add("CacheMemoryLimitMegabytes", Convert.ToString(CacheSize)); 
            CacheSettings.Add("physicalMemoryLimitPercentage", Convert.ToString(49));  //set % here
            CacheSettings.Add("pollingInterval", Convert.ToString("00:00:10"));
            MemCache = new MemoryCache("TestCache", CacheSettings);
        }

        public void AddItem(string Name, string Value)
        {
            CacheItem CI = new CacheItem(Name, Value);
            MemCache.Add(CI, CIPOL);

            lock (Statlock)
            {
                ItemCount++;
                size = size + (Name.Length + Value.Length * 2);
            }

        }

        public void CacheItemRemoved(CacheEntryRemovedArguments Args)
        {
            Console.WriteLine("Cache contains {0} items. Size is {1} bytes", ItemCount, size);

            lock (Statlock)
            {
                ItemCount--;
                size = size - 108;
            }

            Console.ReadKey();
        }
    }
}

namespace FinalCacheTest
{
    internal class Program
    {
        private static void Main(string[] args)
        {
            int MaxAdds = 5000000;
            Cache MyCache = new Cache(1); // set CacheMemoryLimitMegabytes

            for (int i = 0; i < MaxAdds; i++)
            {
                MyCache.AddItem(Guid.NewGuid().ToString(), Guid.NewGuid().ToString());
            }

            Console.WriteLine("Finished Adding Items to Cache");
        }
    }
}

Почему MemoryCache не соответствует установленным ограничениям памяти?

84
задан David Schwartz 20 December 2014 в 08:03
поделиться