응용 프로그램에서 .NET 4.0 MemoryCache 클래스로 작업 하고 최대 캐시 크기를 제한하려고 시도하고 있지만 테스트에서 캐시가 실제로 제한을 따르는 것으로 나타나지 않습니다.
MSDN에 따르면 캐시 크기를 제한하는 설정을 사용하고 있습니다.
- CacheMemoryLimitMegabytes : 개체 인스턴스가 증가 할 수있는 최대 메모리 크기 (MB)입니다. "
- PhysicalMemoryLimitPercentage : "캐시가 사용할 수있는 실제 메모리의 백분율로, 1에서 100 사이의 정수 값으로 표시됩니다. 기본값은 0입니다. 이는 MemoryCache 인스턴스가 컴퓨터에 설치된 메모리 양에 따라자체 메모리 1을 관리함을 나타냅니다. 컴퓨터." 1. 이것은 완전히 정확하지 않습니다. 4 미만의 값은 무시되고 4로 대체됩니다.
캐시를 제거하는 스레드가 x 초마다 실행되고 폴링 간격 및 기타 문서화되지 않은 변수에 따라 달라지기 때문에 이러한 값은 근사치이며 하드 제한이 아님을 이해합니다. 그러나 이러한 차이를 고려하더라도 CacheMemoryLimitMegabytes 및 PhysicalMemoryLimitPercentage를 함께 설정 하거나 테스트 앱에서 단일 항목으로 설정 한 후 첫 번째 항목이 캐시에서 제거 될 때 캐시 크기가 매우 일치하지 않습니다 . 각 테스트를 10 번 실행하고 평균 수치를 계산했습니다.
다음은 RAM이 3GB 인 32 비트 Windows 7 PC에서 아래 예제 코드를 테스트 한 결과입니다. 캐시의 크기는 각 테스트에서 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 가 구성된 메모리 제한을 따르지 않는 이유는 무엇 입니까?