Saya bekerja dengan kelas .NET 4.0 MemoryCache dalam sebuah aplikasi dan mencoba membatasi ukuran cache maksimum, tetapi dalam pengujian saya tidak tampak bahwa cache sebenarnya mematuhi batas.
Saya menggunakan pengaturan yang, menurut MSDN , seharusnya membatasi ukuran cache:
- CacheMemoryLimitMegabytes : Ukuran memori maksimum, dalam megabyte, yang dapat digunakan untuk mengembangkan instance objek. "
- PhysicalMemoryLimitPercentage : "Persentase memori fisik yang dapat digunakan cache, dinyatakan sebagai nilai integer dari 1 hingga 100. Standarnya adalah nol, yang menunjukkan bahwainstance MemoryCache mengelola memori 1 mereka sendiriberdasarkan jumlah memori yang diinstal di komputer." 1. Ini tidak sepenuhnya benar - nilai apa pun di bawah 4 akan diabaikan dan diganti dengan 4.
Saya mengerti bahwa nilai-nilai ini adalah perkiraan dan bukan batas yang sulit karena utas yang membersihkan cache dipecat setiap x detik dan juga bergantung pada interval polling dan variabel tidak berdokumen lainnya. Namun, bahkan dengan mempertimbangkan perbedaan ini, saya melihat ukuran cache yang sangat tidak konsisten saat item pertama dikeluarkan dari cache setelah menyetel CacheMemoryLimitMegabytes dan PhysicalMemoryLimitPercentage bersama-sama atau secara tunggal dalam aplikasi pengujian. Untuk memastikan saya menjalankan setiap tes 10 kali dan menghitung angka rata-rata.
Ini adalah hasil pengujian kode contoh di bawah ini pada PC Windows 7 32-bit dengan RAM 3GB. Ukuran cache diambil setelah panggilan pertama ke CacheItemRemoved () pada setiap pengujian. (Saya tahu ukuran cache sebenarnya akan lebih besar dari ini)
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
Berikut adalah aplikasi tesnya:
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");
}
}
}
Mengapa MemoryCache tidak mematuhi batas memori yang dikonfigurasi?