51

私はMemoryCacheASP.NET で使用していますが、うまく機能しています。リポジトリからデータが新たにプルされるのを防ぐために、1 時間キャッシュされるオブジェクトがあります。

キャッシュがデバッグで機能していることを確認できますが、サーバーにデプロイされた後、最初の呼び出しが行われ、オブジェクトがキャッシュされた後、後続の呼び出しは約 1/5 の時間になります。

ただし、新しいクライアント呼び出し (まだその 1 時間のウィンドウ内 - 実際には 1 ~ 2 分後) のたびに、サービスへの最初の呼び出し (キャッシュを実行している) が元の呼び出しとほぼ同じ時間がかかるように見えることに気付きました。データがキャッシュされる前に呼び出します。

これにより、私は疑問に思い始めました-セッション固有であり、呼び出しを行う新しいクライアントごとに独自のキャッシュが保存されているか、データがキャッシュされていることがわかったMemoryCacheでも、最初の呼び出しに時間がかかる原因となる何かが他にあるのでしょうか?

4

2 に答える 2

83

MSDNから:

Cache クラスと MemoryCache クラスの主な違いは、MemoryCache クラスが変更され、ASP.NET アプリケーションではない .NET Framework アプリケーションで使用できるようになったことです。たとえば、MemoryCache クラスは System.Web アセンブリに依存しません。もう 1 つの違いは、同じアプリケーションおよび同じ AppDomain インスタンスで使用するために、MemoryCache クラスの複数のインスタンスを作成できることです。

MemoryCacheそれを読んで、反映されたコードでいくつかの調査を行うと、単純なクラスであることは明らかです。プロパティを使用MemoryCache.Defaultして同じインスタンスを (再) 使用することも、必要な数のインスタンスを構築することもできます (推奨されるインスタンスはできるだけ少なくします)。

したがって、基本的に答えはコードにあります。
使用するMemoryCache.Defaultと、キャッシュはアプリケーション プールが存続する限り存続します。(デフォルトのアプリケーション プールのアイドル タイムアウトは 20 分で、1 時間未満です。)

を使用して作成する場合new MemoryCache(string, NameValueCollection)、上記の考慮事項に加えて、インスタンスを作成するコンテキストが適用されます。つまり、コントローラー内でインスタンスを作成する場合 (そうではないことを願っています)、キャッシュは 1 つの要求に対して存続します。

参照が見つからないのは残念ですが、MemoryCache指定したキャッシュ ポリシーに従ってデータが保持されることを保証するものではありません。特に、アプリを実行しているマシンがメモリに負荷をかけると、キャッシュが破棄される可能性があります。

それでもキャッシュ アイテムが早期に無効化された理由を突き止めることができない場合は、これを利用してRemoveCallback、アイテムが無効化された理由を調査することができます。

于 2013-05-22T10:29:52.677 に答える
35

1年後にこれを見直したところ、キャッシュがランダムに「ドロップ」するという元の投稿で、さらに詳しい情報が見つかりました。MSDN には、構成可能なキャッシュ プロパティCacheMemoryLimitMegabytesとについて次のように記載されていますPhysicalMemoryLimitPercentage

デフォルト値は 0 です。これは、MemoryCache クラスのオートサイズ ヒューリスティックがデフォルトで使用されることを意味します。

CacheMemoryMonitor.csいくつかの逆コンパイルと調査を行うと、メモリのしきい値を定義するクラスの奥深くに事前定義されたシナリオがあります。AutoPrivateBytesLimitプロパティのそのクラスのコメントのサンプルを次に示します。

// Auto-generate the private bytes limit:
// - On 64bit, the auto value is MIN(60% physical_ram, 1 TB)
// - On x86, for 2GB, the auto value is MIN(60% physical_ram, 800 MB)
// - On x86, for 3GB, the auto value is MIN(60% physical_ram, 1800 MB)
//
// - If it's not a hosted environment (e.g. console app), the 60% in the above
//   formulas will become 100% because in un-hosted environment we don't launch
//   other processes such as compiler, etc.

特定の値が重要であるとは限りませんが、キャッシュが頻繁に使用される理由を理解するのと同じくらい重要です:何度も取得したくない大きなオブジェクトを格納するためです。これらの大きなオブジェクトがキャッシュに格納されていて、これらの内部計算に基づくホスティング環境のメモリしきい値を超えた場合、項目がキャッシュから自動的に削除されることがあります。IISで複数のアプリを実行しているおそらく2GBのメモリを使用して、ホストされたサーバーのメモリに非常に大きなコレクションを保存していたため、これは確かに私のOPを説明できます。

これらの値の設定には、明示的なオーバーライドがあります。構成を介して (またはMemoryCacheインスタンスのセットアップ時に)CacheMemoryLimitMegabytesおよびのPhysicalMemoryLimitPercentage値を設定できます。を 95 (%)に設定した次のMSDNリンクから変更されたサンプルを次に示します。physicalMemoryPercentage

<configuration>
  <system.runtime.caching>
    <memoryCache>
      <namedCaches>
          <add name="default" 
               physicalMemoryLimitPercentage="95" />
      </namedCaches>
    </memoryCache>
  </system.runtime.caching>
</configuration>
于 2014-09-25T15:03:12.570 に答える