2012-03-11 66 views
4

我想在我的應用程序中實現一些緩存,我想在C#中使用默認內存緩存(如果不需要,可以更改此需求)。我的問題是,不想超過機器上的最大物理內存量,但據我所知,我無法將這種約束添加到默認內存緩存中。使用LRU策略的默認內存緩存

一般策略是:

  1. 如果對象已經在高速緩存10分鐘,沒有請求它被刪除
  2. 如果一個新的對象被添加到所述高速緩存和最大量的avaliable物理內存接近使用元素基於LRU

我的緩存可以包含許多不同的對象和它們的範圍從10MB到2-3gb刪除,所以我真的不能得到trim功能工作。

是否有任何關於如何實現LRU緩存監測RAM的使用的建議?並且跳躍地使用.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

看起來像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#中保留內存頁面。

+0

這也是我的想法,如果我的機器有4 GB內存,並且我在4分鐘內填充該緩存,那麼當向緩存中添加更多對象時,緩存將切換到頁面文件,而不是刪除LRU對象。當滑動到期時,它會首先採取行動。 – aweis 2012-03-11 10:01:27

+0

我已經更新了答案,包括如何解決這個問題。大小限制將轉儲對象達到一個限制。分頁無法完全防止。 – saarp 2012-03-11 18:47:12

+0

對於某些reasone,它不會更改屬性值。在實例化之後查看緩存對象時,限制仍然是98! – aweis 2012-03-11 20:01:01