我在ASP.NET中使用MemoryCache
并且运行良好。我有一个缓存了一个小时的对象,以防止从存储库中获取新的数据。
我可以看到缓存在调试中工作,但是一旦部署到服务器,在第一次调用并且缓存了对象之后,后续调用大约是1/5的时间。
但是我注意到每个新的客户端呼叫(仍然在1小时窗口内 - 实际上只是一分钟或2分钟后)似乎第一次调用我的服务(这是做的缓存)在缓存数据之前几乎与原始调用一样长。
这让我开始怀疑 - 特定于MemoryCache
会话,并且每个进行调用的新客户端都存储它自己的缓存,或者是其他一些事情导致第一次调用甚至 之后我知道数据已被缓存了吗?
答案 0 :(得分:69)
来自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
并调查项目失效的原因。
答案 1 :(得分:25)
一年后回顾这一点,我在原帖上发现了一些关于缓存“随机丢弃”的更多信息。 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.
特定的值并不一定与实现为何经常使用缓存一样重要:存储我们不想获取的大型对象并结束。如果这些大型对象存储在缓存中,并且超出了基于这些内部计算的托管环境内存阈值,则可以自动从缓存中删除该项。这当然可以解释我的OP,因为我在托管服务器上存储了一个非常大的集合,可能有2GB的内存在IIS中运行多个应用程序。
设置这些值有明确的覆盖。您可以通过配置(或在设置MemoryCache
实例时)设置CacheMemoryLimitMegabytes
和PhysicalMemoryLimitPercentage
值。以下是MSDN链接的修改示例,其中我将physicalMemoryPercentage
设置为95(%):
<configuration>
<system.runtime.caching>
<memoryCache>
<namedCaches>
<add name="default"
physicalMemoryLimitPercentage="95" />
</namedCaches>
</memoryCache>
</system.runtime.caching>
</configuration>