5

アプリケーションにキャッシュを実装しようとしていますが、C# で既定のメモリ キャッシュを使用したいと考えています (これが機能しない場合は、この要件を変更できます)。私の問題は、マシンにある物理メモリの最大量を超えたくないということですが、私が理解しているように、デフォルトのメモリキャッシュにそのような制約を追加することはできません。

一般に、ポリシーは次のとおりです。

  1. オブジェクトがリクエストなしで 10 分間キャッシュ内にある場合、オブジェクトは削除されます
  2. 新しいオブジェクトがキャッシュに追加され、使用可能な物理メモリの最大量が使用済みに近づくと、LRU に基づいて要素が削除されます

私のキャッシュにはさまざまなオブジェクトが含まれている可能性があり、それらは 10 MB から 2 ~ 3 GB の範囲にあるため、trim機能を実際に動作させることはできません。

RAM の使用状況を監視する LRU キャッシュを実装する方法について何か提案はありますか? うまくいけば、.net のキャッシュを使用して実行できますか?

編集

MemoryCache が 100Mb と物理メモリの 20% に制限されている簡単な例を追加しましたが、何も変わりません。私のメモリは、キャッシュエントリの削除なしでいっぱいです。ポーリング間隔が 5 秒ごとに変更されていることに注意してください。

class Item
{
    private List<Guid> data;

    public Item(int capacity)
    {
        this.data = new List<Guid>(capacity);
        for (var i = 0; i < capacity; i++)
            data.Add(Guid.NewGuid());
    }
}

class Program
{
    static void Main(string[] args)
    {
        var cache = new MemoryCache(
            "MyCache",
            new NameValueCollection
            {
                { "CacheMemoryLimitMegabytes", "100" },
                { "PhysicalMemoryLimitPercentage", "20" },
                { "PollingInterval", "00:00:05" }
            });

        for (var i = 0; i < 10000; i++)
        {
            var key = String.Format("key{0}", i);
            Console.WriteLine("Add item: {0}", key);
            cache.Set(key, new Item(1000000), new CacheItemPolicy() { UpdateCallback = UpdateHandler } );
        }

        Console.WriteLine("\nDone");
        Console.ReadKey();
    }

    public static void UpdateHandler(CacheEntryUpdateArguments args)
    {
        Console.WriteLine("Remove: {0}, Reason: {1}", args.Key, args.RemovedReason.ToString());
    }
}
4

1 に答える 1

4

System.Runtime.Caching.MemoryCacheクラスがこの法案にうまく適合するように見えます。アイテムごとにキャッシュ ポリシーを設定するため、TimeSpan が 10 分で SlidingExpiration のキャッシュ ポリシーを持つアイテムを追加すると、探している動作が得られるはずです。

これは .Net v4 クラスのみであるため、以前のランタイム バージョンには存在しません。Web コンテキストの場合、ASP.Net キャッシュは同様に動作しますが、システム情報を管理できない可能性があります。

特定のメモリ フットプリントを超えないように、作成時にキャッシュ サイズに制限を設定できます。

var myCache = new MemoryCache( 
    "MyCache",
    new NameValueCollection { { "PhysicalMemoryLimit", "50" }} // set max mem pct
    );

これにより、少なくともアプリケーション内で、ディスクへのページングが防止されます。外部メモリ プレッシャーがある場合、またはシステムがメモリをディスクにページングすることに過度に積極的である場合、アプリケーション内での過度の使用が原因ではなく、キャッシュが引き続きページ アウトされる可能性があります。私の知る限り、C# でメモリ ページを予約する方法はありません。

于 2012-03-11T09:22:54.967 に答える