0

我们有处理大量地图数据的 WinForm 应用程序。我们有一个缓存(一个简单的哈希表),我们存储经常访问的地图数据,以加快操作。虽然我们确实限制了缓存的大小,但任务管理器显示了不断增长的内存消耗,最后我们得到了 OutOfMemoryException。 奇怪的是,内存分析器和 GC.GetTotalMemory 以及我们自己的对象大小计算都说了同样的话:我们的缓存永远不会使用超过我们的限制设置的内存。如果我们禁用缓存,我们的系统就可以正常工作:在处理地图数据期间,它会在几秒钟内达到峰值,但之后又会恢复正常。

内存分析器很好地显示已用空间(用绿色表示)与我们的缓存大小完全对应,但大部分保留的内存都没有使用
在分析会话期间,我们拍摄了 4 个内存快照:

  • 内存快照1:缓存开启(最大缓存大小 300MB)
  • 内存快照2:缓存关闭
  • 内存快照3:再次缓存(最大缓存大小 300MB)
  • 内存快照4:缓存再次关闭

观看下面的颜色编码。为什么没有收回那些巨大的未使用空间(蓝色)?调用 GC.Collect 没有区别

内存分析会话,打开和关闭缓存

4

1 回答 1

0

正如汉斯在评论中指出的那样,根本问题是内存碎片。在创建缓存对象(相当大的对象)期间,我们有许多中等大小的瞬态对象,在大型永久对象之间产生了间隙。一旦我们通过重用减少了瞬态对象的数量,碎片就会急剧下降。

正如您在图表中看到的,已用空间:未使用空间的比例为 1:2。修改后的比例为8:1。

于 2013-06-14T14:20:27.130 回答