【问题标题】:Is MemoryCache scope session or application wide?MemoryCache 范围是会话还是应用程序范围?
【发布时间】:2013-05-16 17:55:36
【问题描述】:

我在 ASP.NET 中使用MemoryCache,它运行良好。我有一个缓存了一个小时的对象,以防止从存储库中提取新的数据。

我可以看到缓存在调试中工作,而且一旦部署到服务器,在第一次调用和缓存对象之后,后续调用大约是 1/5 的时间。

但是我注意到每个 new 客户端调用(仍在 1 小时窗口内 - 实际上只是一分钟或 2 分钟后)似乎对我的服务进行了第一次调用(即缓存)花费的时间几乎与缓存数据之前的原始调用时间一样长。

这让我开始怀疑 - 是 MemoryCache 会话特定的,并且每个进行调用的新客户端都在存储它自己的缓存,还是其他原因导致第一次调用需要这么长时间甚至 我知道数据已经被缓存了?

【问题讨论】:

标签: asp.net caching memorycache


【解决方案1】:

来自MSDN

Cache 和 MemoryCache 类之间的主要区别是 已更改 MemoryCache 类以使其可供 .NET 使用 不是 ASP.NET 应用程序的框架应用程序。例如, MemoryCache 类不依赖于 System.Web 程序集。 另一个区别是您可以创建多个实例 MemoryCache 类用于同一应用程序和同一 AppDomain 实例。

阅读并在反射代码中进行一些调查很明显MemoryCache 只是一个简单的类。您可以使用MemoryCache.Default 属性来(重新)使用相同的实例,或者您可以构建任意数量的实例(尽管建议尽可能少)。

所以基本上答案就在您的代码中。
如果您使用MemoryCache.Default,那么只要您的应用程序池存在,您的缓存就会存在。 (提醒您,默认应用程序池空闲超时时间为 20 分钟,小于 1 小时。)

如果您使用new MemoryCache(string, NameValueCollection) 创建它,则上述注意事项适用加上您创建实例的上下文,也就是说,如果您在控制器内创建实例(我希望不是这种情况),那么您的缓存会存在请求

很遗憾我找不到任何引用,但是...MemoryCache 不保证根据您指定的缓存策略保存数据。特别是如果您运行应用程序的机器内存压力过大,您的缓存可能会被丢弃。

如果您仍然无法弄清楚缓存项早期失效的原因,您可以利用RemoveCallback 并调查项失效的原因。

【讨论】:

  • 优秀的彻底答案,感谢您提醒有关应用程序池超时。事件虽然不能解释每分钟的解释,但总体上还是有用的。我正在使用MemoryCache.Defaultcache.AddOrGetExisting。在调试期间,逻辑工作得很好。并且同一客户端的快速后续请求按预期从缓存中提取。这是调查我的问题的重要信息。
  • 我想为你 +1,但那会让你 70 岁,我觉得这是一种伤害。
【解决方案2】:

一年后回顾这篇文章,我在原来的帖子中发现了更多关于缓存“随机删除”的信息。 MSDN 对可配置缓存属性 CacheMemoryLimitMegabytesPhysicalMemoryLimitPercentage 声明如下:

默认值为0,表示MemoryCache类的 默认情况下使用 autosize 启发式。

进行一些反编译和调查后,CacheMemoryMonitor.cs 类深处有一些预先确定的场景来定义内存阈值。以下是 AutoPrivateBytesLimit 属性上该类中的 cmets 示例:

// 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.

特定的值并不一定像理解为什么经常使用缓存一样重要:存储我们不想获取的对象和结束。如果这些大型对象被存储在缓存中,并且超出了基于这些内部计算的托管环境内存阈值,则您可能会自动从缓存中删除该项目。这当然可以解释我的 OP,因为我在托管服务器上的内存中存储了一个非常大的集合,其中可能有 2GB 的内存在 IIS 中运行多个应用程序。

设置这些值有一个明确的覆盖。您可以通过配置(或在设置MemoryCache 实例时)设置CacheMemoryLimitMegabytesPhysicalMemoryLimitPercentage 值。这是来自以下MSDN 链接的修改示例,我将physicalMemoryPercentage 设置为95 (%):

<configuration>
  <system.runtime.caching>
    <memoryCache>
      <namedCaches>
          <add name="default" 
               physicalMemoryLimitPercentage="95" />
      </namedCaches>
    </memoryCache>
  </system.runtime.caching>
</configuration>

【讨论】:

  • 这很有帮助。谢谢。
猜你喜欢
  • 1970-01-01
  • 2011-07-01
  • 1970-01-01
  • 2012-08-19
  • 1970-01-01
  • 1970-01-01
  • 2011-01-14
  • 2015-08-02
  • 2012-02-12
相关资源
最近更新 更多