Я работаю с классом .NET 4.0 MemoryCache в приложении и пытаюсь ограничить максимальный размер кеша, но в моих тестах не оказалось, что кеш фактически подчиняясь ограничениям.
Я использую настройки, которые согласно MSDN должны ограничивать размер кеша:
- CacheMemoryLimitMegabytes : максимальный размер памяти в мегабайтах, который является экземпляром объект может вырасти до. "
- 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 не соответствует установленным ограничениям памяти?