【发布时间】:2013-09-04 06:46:01
【问题描述】:
我正在使用 ANTS 内存分析器来诊断我在我的一个 .NET 2.0 应用程序中面临的内存泄漏增加。 我在 7.5 小时内拍摄了该过程的 7 个快照,这是所获得数据的表格表示形式 -
G1 代表第 1 代大小和 G2 第 2 代大小。除非托管空间和私有字节外,所有其他值均以 MB 为单位。
我的问题是 -
为什么即使堆大小很小,未使用的 .NET 空间也会如此之高?
我的大型对象堆达到最大 2 MB,并且在最后 3 个快照期间保持在 96 KB。那为什么会有这么高的大碎片,是它们造成的高未使用空间吗?
非托管空间不断增加。这是否会导致私有字节随着时间的推移而增加?
我无能为力解决这个问题,并进行了多次分析,但找不到合适的解决方案。我已准备好提供所需的任何其他数据。
【问题讨论】:
-
这可能是对象留在内存中的结果。也许您应该验证所有使用的对象都已妥善处理,因为不断的重新实例化将意味着分配更多的内存空间。这也可能是碎片的原因
-
LOH 上的对象很少。分析器显示了一个数组,该数组自应用程序启动以来一直保留在其上,并且另一个数组按预期的定期间隔分配和取消分配。
-
第二个阵列是否布置正确? LOH 中的 GC 是非常罕见的事件。可能的情况是您的第二个数组在 GC 之前被分配,因此可能的情况可能如下所示:[1,2](应用程序的开始)[1,2,2](第二个数组重新分配)当你在 LOH 中得到 GC,你的 LOH 看起来像:[1,0,0,0,0,2] 然后你开始再次分配第二个数组,并得到:[1,2,0,0, 0,2] 如果第二个数组的长度不是恒定的,情况可能会更糟。这个想法是不允许在 LOH 中进行太多重新分配。
-
@Alex :我正在调用第二个数组及其所有子数组的 dispose。但是是的,它可以是可变大小的。
-
@Cygnus:首先,我想推荐阅读这篇文章:simple-talk.com/dotnet/.net-framework/… 它让您了解当重新分配的数组具有可变大小时会发生什么。第二个建议是不要使用数组(在这种情况下)它们会在 LOH 中产生很多间隙。可能 List 或 BigList(来自 PowerCollections)可能是选项。关键是不要在每次需要新集合时都调用“新”。使用 Clear() 并将数据写入已分配的内存。为你分配的每一个字节而战!
标签: .net memory-management red-gate-ants memory-fragmentation