![ASP.NET 缓存修剪了解应用程序池内存限制吗?](https://linux22.com/image/522981/ASP.NET%20%E7%BC%93%E5%AD%98%E4%BF%AE%E5%89%AA%E4%BA%86%E8%A7%A3%E5%BA%94%E7%94%A8%E7%A8%8B%E5%BA%8F%E6%B1%A0%E5%86%85%E5%AD%98%E9%99%90%E5%88%B6%E5%90%97%EF%BC%9F.png)
我在 Win2003 32 位上运行 ASP.NET 应用程序,该应用程序往往会分配大量内存。为了避免在 W3P 进程超过 1 GB 时开始出现的 OutOfMemoryExceptions,我为此应用程序池设置了 850 MB 的最大虚拟内存限制,因此应用程序将重新启动而不是抛出异常。
虽然没有抛出异常,但这些重启仍然会导致暂时的性能下降(低缓存命中率、aspx 编译等),所以我想尽量减少重启次数。观察性能计数器,我可以看到 ASP.NET 缓存按设计工作(启动后项目数和缓存命中率增加,一段时间后,一些项目可能由于过期而被删除),除了缓存修剪。
例如,我预计当使用 750 MB 且其中一半是缓存时,缓存修剪会启动。但这从未发生过,在负载下,它会继续分配越来越多的内存,而不是丢弃低优先级缓存项,直到达到内存限制。
有人知道什么会真正触发缓存修剪吗?可用物理内存?还有其他设置可用于优化这种情况吗?
(是的,我知道,32 位是 2004 年的,而使用 x64 这个问题就会消失,甚至可能使用相同数量的内存,但对于这个应用程序,我还需要在这个服务器上再呆几个月,并且必须保持它运行......)
答案1
我终于找到了问题所在。ASP.NET 缓存有一个可选的 web.config 配置部分: https://msdn.microsoft.com/en-us/library/ms164606(v=vs.100).aspx
对于具有超过 2 GB RAM 的 32 位机器来说,默认配置绝对是无稽之谈:如果少于物理 RAM 的 10%可用。例如,安装了 4 GB 的 RAM 并且每个进程的限制为 2 GB,这种情况永远不会发生。因此,缓存大小(以及堆大小,主要是第 2 代堆)会不断增加,直到您遇到 OutOfMemoryExceptions 或达到应用程序池限制。
现在我将其添加到我的 web.config 中:
<configuration>
<system.web>
<caching>
<cache privateBytesLimit="400000000" privateBytesPollTime="00:01:00" />
</caching>
</system.web>
</configuration>
此外,我还为应用程序池设置了以下限制:
- 1400 MB 虚拟内存限制
- 已用内存限制为 800 MB(私有字节)
请参阅这篇精彩文章来了解这些价值观的背景: http://msdn.microsoft.com/en-us/library/ms972959#monitor_perf_topic10
现在,如果我以一种在短时间内将大量对象添加到缓存中的方式对我的应用程序进行负载测试,我可以看到 ASP.NET 缓存修剪性能计数器上升,并且内存使用量始终保持在我的重新启动限制之下。