Bir uygulamada .NET 4.0 MemoryCache sınıfıyla çalışıyorum ve maksimum önbellek boyutunu sınırlamaya çalışıyorum, ancak testlerimde önbelleğin aslında sınırlara uyuyor gibi görünmüyor.
MSDN'ye göre önbellek boyutunu sınırlaması gereken ayarları kullanıyorum :
- CacheMemoryLimitMegabytes : Bir nesnenin bir örneğinin büyüyebileceği megabayt cinsinden maksimum bellek boyutu. "
- PhysicalMemoryLimitPercentage : "Önbelleğin kullanabileceği fiziksel bellek yüzdesi, 1'den 100'e kadar bir tamsayı olarak ifade edilir. Varsayılan sıfırdır; bu, MemoryCache örneklerinin cihazda yüklü bellek miktarına görekendi belleğini 1 yönettiğinigösterir. bilgisayar." 1. Bu tamamen doğru değildir - 4'ün altındaki herhangi bir değer göz ardı edilir ve 4 ile değiştirilir.
Önbelleği temizleyen iş parçacığı her x saniyede bir tetiklendiğinden ve ayrıca yoklama aralığına ve diğer belgelenmemiş değişkenlere bağlı olduğundan, bu değerlerin yaklaşık olduğunu ve kesin sınırlar olmadığını anlıyorum. Ancak, bu farklılıkları hesaba katarsak bile , bir test uygulamasında CacheMemoryLimitMegabytes ve PhysicalMemoryLimitPercentage'ı birlikte veya tekil olarak ayarladıktan sonra ilk öğe önbellekten çıkarıldığında çılgınca tutarsız önbellek boyutları görüyorum . Emin olmak için her testi 10 kez çalıştırdım ve ortalama rakamı hesapladım.
Bunlar, aşağıdaki örnek kodun 3 GB RAM ile 32 bit Windows 7 bilgisayarda test edilmesinin sonuçlarıdır. Önbelleğin boyutu , her testte ilk CacheItemRemoved () çağrısından sonra alınır . (Önbellek boyutunun bundan daha büyük olacağının farkındayım)
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
İşte test uygulaması:
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 neden yapılandırılmış bellek sınırlarına uymuyor ?