ฉันกำลังทำงานกับคลาส. NET 4.0 MemoryCacheในแอปพลิเคชันและพยายาม จำกัด ขนาดแคชสูงสุด แต่ในการทดสอบของฉันไม่ปรากฏว่าแคชเป็นไปตามขีด จำกัด
ฉันใช้การตั้งค่าซึ่งตาม MSDNควร จำกัด ขนาดแคช:
- CacheMemoryLimitMegabytes : ขนาดหน่วยความจำสูงสุดเป็นเมกะไบต์ที่อินสแตนซ์ของวัตถุสามารถขยายได้ "
- PhysicalMemoryLimitPercentage : "เปอร์เซ็นต์ของหน่วยความจำฟิสิคัลที่แคชสามารถใช้ได้แสดงเป็นค่าจำนวนเต็มตั้งแต่ 1 ถึง 100 ค่าดีฟอลต์คือศูนย์ซึ่งบ่งชี้ว่าอินสแตนซ์ MemoryCacheจัดการหน่วยความจำ 1ของตนเองตามจำนวนหน่วยความจำที่ติดตั้งบน คอมพิวเตอร์." 1.สิ่งนี้ไม่ถูกต้องทั้งหมด - ค่าใด ๆ ที่ต่ำกว่า 4 จะถูกละเว้นและแทนที่ด้วย 4
ฉันเข้าใจว่าค่าเหล่านี้เป็นค่าโดยประมาณและไม่ใช่ข้อ จำกัด อย่างหนักเนื่องจากเธรดที่ล้างแคชจะเริ่มทำงานทุกๆ x วินาทีและยังขึ้นอยู่กับช่วงเวลาการสำรวจและตัวแปรอื่น ๆ ที่ไม่มีเอกสาร อย่างไรก็ตามแม้จะคำนึงถึงความแปรปรวนเหล่านี้ แต่ฉันก็เห็นขนาดแคชที่ไม่สอดคล้องกันอย่างมากเมื่อรายการแรกถูกขับออกจากแคชหลังจากตั้งค่าCacheMemoryLimitMegabytes และPhysicalMemoryLimitPercentageร่วมกันหรือเอกพจน์ในแอปทดสอบ เพื่อให้แน่ใจว่าฉันทำการทดสอบแต่ละครั้ง 10 ครั้งและคำนวณตัวเลขเฉลี่ย
นี่คือผลลัพธ์ของการทดสอบโค้ดตัวอย่างด้านล่างบนพีซี Windows 7 32 บิตที่มี RAM 3GB ขนาดของแคชถูกใช้หลังจากการเรียกครั้งแรกไปยัง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 จึงไม่ปฏิบัติตามขีด จำกัด หน่วยความจำที่กำหนดไว้