我目前正在开发一个网站,该网站大量使用缓存数据以避免往返传输。
在启动时,我们会获取一个“大型”图形(数十万个不同种类的对象)。
这些对象通过WCF进行检索和反序列化(我们使用协议缓冲区进行序列化)。
我正在使用redgate的内存分析器来调试内存问题(内存似乎与我们初始化后应需要的内存量不符,并且最终得到以下报告:
现在我们可以从这份报告中得出以下结论:
1).NET分配的大部分内存是空闲的(它可能在反序列化期间被正确地分配,但现在已经空闲,希望它返回到操作系统中)。
2)内存是碎片化的(这很糟糕,因为每次刷新缓存时,我都需要重新进行耗费内存的反序列化过程,这反过来会创建大型对象,由于碎片化而可能引发OutOfMemoryException)。
3)我不知道空间为什么是碎片化的,因为当我查看大型对象堆时,只有30个实例,其中15个object[]直接附加到GC并与我无关,1个char数组也直接附加到GC堆上,其余的15个都是我的,但不是造成这个问题的原因,如果我在代码中注释掉它们,我会得到相同的报告。
所以我的问题是,我该怎么做才能进一步解决这个问题? 我不太确定在调试/工具中要寻找什么,因为似乎我的内存是碎片化的,但不是由我造成的,并且大量的空闲空间由.NET分配,我无法释放。
此外,请确保在回答前充分理解问题,我不是在寻找释放.NET内存(GC.Collect)的方法,而是释放已经在.NET中空闲的内存,并将该内存碎片整理好后返回给操作系统。
请注意,如果可以手动碎片整理大堆内存,即使解决方案较慢,也没有关系,因为我可以在RefreshCache的末尾调用它,并且执行需要1或2秒也无妨。感谢您的帮助!
我忘记了几点: 1)该项目是一个.NET 2.0网站,在.NET 4池中运行它会得到相同的结果,即使我将其转换为.NET 4并重新编译也是如此。
2)这些都是发布版本的结果,因此调试版本不可能是问题所在。
3)这可能非常重要,我在WebDev服务器中根本没有遇到这些问题,只有在IIS中才有,而在WebDev中,我得到的内存消耗非常接近我的实际消耗(多一些,但不是5-10倍!)