我最近也经历过这个。考虑到内存缓存将是特定于进程的(不会在网站或本地业务应用程序或多个服务器的多个实例之间共享),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}”的缓存键。将其视为缓存条目的名称间隔。
希望有帮助!