如何在ASP.NET缓存应用程序中超过IIS7的60%内存限制

6

如果这个问题更偏向服务器错误(serverfault)而不是stackoverflow,请不要介意。它似乎处于边缘地带。

我们有一个使用ASP.NET缓存的电子商务应用程序,它缓存了大量的产品数据。这是一个包含65K元素的字典对象,我们的计算结果将该对象的大小定为约10GB。
问题:

  1. 对象消耗的内存量似乎远远超出了我们10GB的计算。

  2. 最大的关注点:我们似乎不能使用服务器中32GB以上的60%。

到目前为止我们尝试过的:

在machine.config/system.web(sf不允许标签,对格式表示歉意)中:

processModel autoConfig="true" memoryLimit="80"

在web.config/system.web/caching/cache(sf不允许标签,格式可能有误)中:
 privateBytesLimit = "20000000000" (and 0, the default of course)
 percentagePhysicalMemoryUsedLimit = "90" 

环境: Windows 2008R2 x64 32GB RAM IIS7

我们似乎无法超过60%的值。 请参见任务管理器的截图。

http://www.freeimagehosting.net/image.php?7a42144e03.jpg


一个有根据的猜测:服务器正在重新调整其内存以适应您投入的增加工作量,使用更多的交换文件来进行补偿,或者更快地进行垃圾回收。类似这样的情况。当您增加负载时,任务管理器中的性能选项卡是什么样子的?交换文件的大小是否增加? - Robert Harvey
@Robert:交换基本保持不变(这很有道理,因为它是内存缓存)。但还值得检查一下。 @all: 我在想单个对象的大小是否是问题所在。 GC是否需要一定数量的“松弛空间”来移动对象,而这个“一个”对象超出了那个范围? - evilknot
它总是在相同的内存使用点失败吗?在死亡时事件日志中有任何信息吗?另一个随机猜测是内存碎片化。如果在它死亡之前附加了调试器,当它死亡时是否会抛出任何异常?(例如OOM) - James Manning
@James:是的,它肯定会抛出一个内存不足错误,同时还有一个YSOD。 - evilknot
听起来像是内存碎片问题 - 在我看来,如果可能的话,我会考虑以不同的方式进行缓存,或者更容易的方法,增加更多的内存? :) - James Manning
显示剩余2条评论
2个回答

2
有点晚了,但我碰到了几乎相同的问题。在 processModel 上设置 memoryLimit 的问题在于,尽管文档中如此说明,但它似乎毫无作用。 percentagePhysicalMemoryUsedLimit 看起来也应该有作用,但实际上没有。 privateBytesLimit="20000000000" 确实有效。我进行了进程调试,并找到了 CacheMemorySizePressure 对象,它成功地接收了该值并将其设置为 _memoryLimit。您可以再次核实一下。
另一个选择是在 IIS 应用程序池上设置私有内存使用回收阈值。这也应该被识别并覆盖默认的 60% 限制。
第三个选择是使用新的 MemoryCache 类,并在其中设置 PhysicalMemoryLimit

1

你有没有考虑使用不同的缓存策略?内置的缓存功能并不是很丰富,除非有一些 IIS 大师有一些聪明的方法,否则你将很难让它做更多的事情。

我们花了很多时间来研究这个问题,但最终放弃了。我们实际上使用更简单的对象存储在缓存中,并在需要时获取更完整的对象。

当我们需要考虑这个问题时,我们调查了 Memcached 和 Velocity,但暂时还没有部署它们。它们的功能更加丰富。

此外,你是如何通过代码将项目存储在缓存中的?是在应用程序启动时还是在每个请求后放入缓存中的?我问这个问题是因为你的缓存键是否有效,实际上你正在重复填充缓存而不是检索任何内容(这可能只是一个对象类型的情况)。例如,我们曾经通过将时间附加到特定日期的缓存键来完成这个操作。


我们正在探索其他缓存。我们只是在应用程序启动时一次性填充缓存,它不会改变。除了 nCache,我们还研究了上述内容。谢谢! - evilknot
1
+1,这里的asp.net缓存真的很糟糕--你可能需要其他的解决方案,比如进程外缓存。 - Wyatt Barnett

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接