【问题标题】:.NET application memory usage - high unused .NET and unmanaged memory and fragmentation.NET 应用程序内存使用率 - 高未使用的 .NET 和非托管内存和碎片
【发布时间】:2013-09-04 06:46:01
【问题描述】:

我正在使用 ANTS 内存分析器来诊断我在我的一个 .NET 2.0 应用程序中面临的内存泄漏增加。 我在 7.5 小时内拍摄了该过程的 7 个快照,这是所获得数据的表格表示形式 -

G1 代表第 1 代大小和 G2 第 2 代大小。除非托管空间和私有字节外,所有其他值均以 MB 为单位。

我的问题是 -

  1. 为什么即使堆大小很小,未使用的 .NET 空间也会如此之高?

  2. 我的大型对象堆达到最大 2 MB,并且在最后 3 个快照期间保持在 96 KB。那为什么会有这么高的大碎片,是它们造成的高未使用空间吗?

  3. 非托管空间不断增加。这是否会导致私有字节随着时间的推移而增加?

我无能为力解决这个问题,并进行了多次分析,但找不到合适的解决方案。我已准备好提供所需的任何其他数据。

【问题讨论】:

  • 这可能是对象留在内存中的结果。也许您应该验证所有使用的对象都已妥善处理,因为不断的重新实例化将意味着分配更多的内存空间。这也可能是碎片的原因
  • 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


【解决方案1】:

正如 Alex 已经指出的,这里可以找到对问题类大对象堆碎片的一个很好的解释:

https://www.simple-talk.com/dotnet/.net-framework/the-dangers-of-the-large-object-heap/

这个问题在 .NET FX 开发团队中是众所周知的,并且一直在解决。 使用更新的 FX 版本,这些症状很有可能会消失。

从 .NET 4.5.1 开始,将会有一个 GC 方法调用来压缩 LOH: http://blogs.msdn.com/b/mariohewardt/archive/2013/06/26/no-more-memory-fragmentation-on-the-large-object-heap.aspx 但是,找到 LOHF 的根本原因将比仅仅擦除它浪费大量的 ms 更有效

如果您需要更多详细信息如何隔离此类影响,请告诉我。

赛博

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-12-27
    • 2013-09-16
    • 2017-09-08
    • 2013-08-18
    • 1970-01-01
    相关资源
    最近更新 更多