使用MemoryCache的多个实例

Adi*_*ter 68 .net c# caching .net-4.0 memorycache

我想使用System.Runtime.Caching命名空间向我的应用程序添加缓存功能,并且可能希望在几个地方和不同的上下文中使用缓存.为此,我想使用几个MemoryCache实例.

但是,我在这里看到不鼓励使用多个MemoryCache实例:

MemoryCache不是单例,但是您应该只创建一些或者可能只创建一个MemoryCache实例,缓存项目的代码应该使用这些实例.

多个MemoryCache实例将如何影响我的应用程序?我发现这种奇怪,因为在我看来,在应用程序中使用多个缓存是一种非常常见的情况.

编辑:更具体地说,我有一个类应该为每个实例保留一个缓存.我应该避免使用MemoryCache并寻找不同的缓存解决方案吗?MemoryCache在这种情况下使用是否被认为是坏的,如果是这样,为什么?

Ben*_*yne 67

我最近自己也经历过这个.考虑到内存缓存将是特定于进程的(不在网站或本机业务应用程序或多个服务器的多个实例之间共享)MemoryCache除了代码组织原因(可以通过其他方式实现)之外,拥有多个实例实际上没有任何好处.

内存缓存主要是因为其内存管理功能而单独使用.除了性能计数器(确实有一些开销)之外,MemoryCache还可以在分配的内存耗尽时使项目过期.

如果高速缓存的当前实例超过CacheMemoryLimit属性设置的内存限制,则高速缓存实现将删除高速缓存条目.应用程序中的每个缓存实例都可以使用CacheMemoryLimit属性指定的内存量.

来自MemoryCache.CacheMemoryLimit属性

通过仅使用MemoryCache的一个实例,它可以在整个应用程序实例中有效地应用此内存管理.在整个应用程序中使最不重要的项目到期.这确保了最大的内存使用,而不会超出您的硬件功能.通过限制任何一个MemoryCache的范围(比如一个类的一个实例),它不再能够有效地管理应用程序的内存(因为它无法"看到"所有内容).如果所有这些缓存都"忙",那么管理内存可能会更难,而且它永远不会那么高效.

这在没有专用服务器的应用程序中特别敏感.想象一下,您正在共享服务器上运行您的应用程序,在该服务器上您只分配了150mb RAM(普通便宜10美元/月托管),您需要依靠缓存来最大限度地使用它而不超过它.如果超过此内存使用量,您的应用程序池将被回收,您的应用程序将丢失所有内存缓存!(常见的廉价托管实践)同样适用于在某些共享企业服务器上托管的非Web应用程序.同样的交易,你被告知不要占用该机器上的所有内存,并与其他一系列商业应用程序和平共存.

内存限制,应用程序池回收,丢失缓存的东西是Web应用程序常见的"阿基里斯之踵".当应用程序最繁忙时,由于超出内存分配而丢失所有缓存条目,因此最常重置,因此最重要的工作是重新获取应该首先缓存的内容.这意味着应用程序实际上在最大负载而不是获得时失去了性能.

我知道MemoryCache是​​System.Web.Caching.Cache实现的非Web特定版本,但这说明了缓存实现背后的逻辑.如果您没有独占使用硬件,则可以在非Web项目中应用相同的逻辑.请记住,如果您的缓存强制机器开始执行页面文件交换,那么缓存不再比磁盘缓存快.你总是希望某个地方有限制,即使这个限制是2GB或者其他什么.

在我阅读了这篇文章之后,我转而在我的应用程序中使用一个"公共静态MemoryCache",我只是通过缓存键来隔离缓存项目.例如,如果要在每个实例上进行缓存,则可以使用类似"instance- {instanceId} -resourceName- {resourceId}"的缓存键.可以将其视为名称间隔缓存条目.

希望有所帮助!

  • 谢谢,这很有帮助.但是,我不打算根据内存大小限制我的缓存,但可能是根据容量限制 - 我希望每个实例都具有一定的容量,而我不关心组合缓存.按命名约定隔离缓存项对于这种情况并不好,并且看起来有点被迫. (2认同)

Kit*_*Kit 6

我也用了几个.通常每种类型一种.

看着MemoryCache我看到它挂钩AppDomain事件并维护性能计数器.我怀疑通过使用多个(例如CPU,计数器和内存),在资源方面有一些开销,这就是为什么不鼓励它.