Estoy trabajando con la clase MemoryCache .NET 4.0 en una aplicación y trato de limitar el tamaño máximo de caché, pero en mis pruebas no parece que la caché esté cumpliendo los límites.
Estoy usando la configuración que, según MSDN , se supone que limita el tamaño de la caché:
- CacheMemoryLimitMegabytes : el tamaño máximo de memoria, en megabytes, al que puede crecer una instancia de un objeto ".
- PhysicalMemoryLimitPercentage : "El porcentaje de memoria física que puede usar la caché, expresado como un valor entero de 1 a 100. El valor predeterminado es cero, lo que indica que las instancias de MemoryCache administran su propia memoria 1 según la cantidad de memoria que está instalada en el computadora." 1. Esto no es del todo correcto: cualquier valor por debajo de 4 se ignora y se reemplaza por 4.
Entiendo que estos valores son aproximados y no límites estrictos, ya que el hilo que purga el caché se activa cada x segundos y también depende del intervalo de sondeo y otras variables no documentadas. Sin embargo, incluso teniendo en cuenta estas variaciones, veo tamaños de caché tremendamente inconsistentes cuando el primer elemento se expulsa de la caché después de configurar CacheMemoryLimitMegabytes y PhysicalMemoryLimitPercentage juntos o de forma singular en una aplicación de prueba. Para estar seguro, ejecuté cada prueba 10 veces y calculé la cifra promedio.
Estos son los resultados de probar el código de ejemplo a continuación en una PC con Windows 7 de 32 bits con 3 GB de RAM. El tamaño de la caché se toma después de la primera llamada a CacheItemRemoved () en cada prueba. (Soy consciente de que el tamaño real de la caché será mayor que esto)
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
Aquí está la aplicación de prueba:
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");
}
}
}
¿Por qué MemoryCache no obedece los límites de memoria configurados?