Я працюю з класом .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 не дотримується налаштованих обмежень пам'яті?