最近我自己也经历了这件事.考虑到内存中的缓存将是特定于进程的(不会在网站的多个实例或本地业务应用程序或多个服务器之间共享),除了代码组织原因(可以通过其他方式实现)外,拥有多个MemoryCache
个实例实际上没有任何好处.
内存缓存主要用于单独使用,因为它具有内存管理功能.除了性能计数器(确实有一些开销)外,当内存缓存耗尽分配的内存时,它还能够使项过期.
如果缓存的当前实例超过了内存集的限制
从MemoryCache.CacheMemoryLimit Property
通过只使用MemoryCache的一个实例,它可以在整个应用程序实例中有效地应用这种内存管理.使整个应用程序中最不重要的项过期.这确保了最大限度地使用内存,而不会超出硬件能力.通过限制任何一个MemoryCache的范围(比如一个类的一个实例),它无法再有效地管理应用程序的内存(因为它无法"看到"所有内容).如果所有这些缓存都处于"繁忙"状态,那么管理内存的难度可能会更大,而且它的效率也永远不会这么高.
这在没有专用服务器的应用程序中尤其敏感.假设你在一个共享服务器上运行应用程序,在这个服务器上你只分配了150mb内存(普通廉价的每月10美元托管),你需要依靠缓存最大限度地使用它,而不超过它.如果超过此内存使用量,你的应用程序池将被回收,你的应用程序将丢失所有内存缓存!(常见的廉价托管做法)这同样适用于内部托管在某个共享公司服务器上的非web应用程序.同样的交易,你被告知不要占用那台机器上的所有内存,并与其他业务应用和平共处.
内存限制、应用程序池回收、丢失缓存是web应用程序的常见"致命弱点".当应用程序最忙时,由于内存分配过多、丢失所有缓存项,它们重置的频率最高,因此在重新获取本来应该缓存的内容时所做的工作最多.这意味着应用程序实际上会在最大负载下失go 性能,而不是获得性能.
我知道MemoryCache是System.Web.Caching.Cache实现的非web特定版本,但这说明了缓存实现背后的逻辑.如果您没有对硬件的独占使用,同样的逻辑也可以应用于非Web项目.请记住,如果您的缓存强制机器开始执行页面文件交换,那么您的缓存不再比磁盘上的缓存快.您总是希望在某个地方设置一个限制,即使该限制是2 GB或更高.
在我的 case 中,在阅读了相关内容后,我在应用程序中改用了一个"公共静电内存缓存",并简单地按照缓存项的缓存键来分隔缓存项.例如,如果您想在每个实例上缓存,您可以有一个类似于"instance-{instanceId}-resourceName-{resourceId}".的缓存键可以将其视为缓存条目的名称间隔.
希望有帮助!