【问题标题】:.net application object promoted to gen 2.net 应用程序对象提升到第 2 代
【发布时间】:2012-08-01 13:05:23
【问题描述】:

很长一段时间以来,我一直在尝试修复我的应用程序中的内存泄漏。几个月前,我注意到在我的应用程序中,超过 95% 的对象被提升到 Gen2;我有一些非常基本的问题,我无法在书中找到。我希望你们能帮助我:

  1. 拥有这么多 Gen2 对象是个坏消息吗?在我拍摄的每个快照中,我都会在 WinDbg 中获得大约 77,000 个 Gen2 对象、100 个 Gen1 对象和 10 个 Gen0 对象。
  2. 我怎样才能找出这么多对象得到提升的原因?有什么好的工具吗?我一直在使用 WinDbg/SOS,但运气不佳

提前谢谢你。

【问题讨论】:

  • 就个人而言,过去使用ANTS Memory Profiler 帮助了我很多。这是一款商业工具,可免费试用 14 天。
  • 为什么你认为你有内存泄漏?
  • 你的申请是什么?对象最终出现在 Gen2 中,因为当 Gen1 集合发生时,您的代码中仍然存在对它们的引用;如果没有一些代码,我们无法诊断出这种情况。
  • @DanPuzey 我不能把代码放在这里;一个有版权限制,而且代码太大
  • 好吧,我们需要一些级别的额外细节来弄清楚发生了什么。 77k 个对象是什么?

标签: c# .net windbg


【解决方案1】:

拥有这么多 Gen2 对象是个坏消息吗?

这不是坏消息。这可能意味着 GC.Collect 刚刚运行,或者它经常运行,并且您有足够的可用内存 - 因此 Gen2 中的对象不会被收集。这是另一个 StackOverflow 问题的一些很好的解释, Garbage Collection not happening even when needed:

开始垃圾收集时,GC 会确定需要收集哪些代(0、0+1 或全部)。每一代都有一个由 GC 确定的大小(它可以随着应用程序的运行而改变)。如果只有第 0 代会超出其预算,那是唯一将收集垃圾的代。如果第 0 代幸存的对象会导致第 1 代超出其预算,那么第 1 代也将被收集并将其幸存对象提升到第 2 代(这是微软实现中的最高代)。如果也超出了第 2 代的预算,则会收集垃圾,但无法将对象提升到更高的一代,因为不存在。

所以,这里有重要的信息,在最常见的 GC 启动方式中,只有在第 0 代和第 1 代都已满时才会收集第 2 代。此外,您需要知道超过 85,000 字节的对象不会存储在第 0、1 和 2 代的普通 GC 堆中。它实际上存储在所谓的大对象堆 (LOH) 中。 LOH 中的内存仅在 FULL 收集期间(即第 2 代收集时)被释放;永远不会只收集第 0 代或第 1 代。

关于你的第二个问题:

我怎样才能找出这么多对象被提升的原因?有什么好的工具吗?我一直在使用 WinDbg/SOS,但运气不佳

Windbg 和 SOS 很好 :) 在这种情况下,我建议添加 psscor2(或 psscor4,如果使用 .NET 4.0)您需要使用 psscor 轻松转储特定代的对象。

这里是下载psscor2psscor4 dll 的官方链接。将它们的适当版本放在安装 Windbg 的文件夹中。 x86 版本的 dll 到 x86 文件夹(C:\Program Files (x86)\Debugging Tools for Windows),x64 版本的 dll 到 x64 文件夹(C:\Program Files\Debugging Tools for Windows (x64))。

然后你就可以运行下一条命令了:

    !dumpheap -gen 2

SOS 没有简单的命令来仅转储特定代的对象,而 psscor 可以。

使用此命令,您可以创建类似的结构

.foreach (obj { !dumpheap -gen 2 -short }) { !do ${obj} }

.foreach (obj { !dumpheap -gen 2 -type ExactTypeName -short }) { !gcroot ${obj} }

找出第2代对象的主要类型,以及哪些方法引用它们。

正如您所说,您的主要想法是查找内存泄漏,您应该使用更通用的方法,并且不仅仅分析生成。以下是我关于分析高内存使用问题的帖子:

托管内存

http://kate-butenko.blogspot.com/2012/06/investigating-memory-issues-high-memory.html

非托管内存

http://kate-butenko.blogspot.com/2012/07/investigating-issues-with-unmanaged.html

http://www.codeproject.com/Articles/31382/Memory-Leak-Detection-Using-Windbg

如果您仍然停留在某个步骤,请留下您的问题。

【讨论】:

    猜你喜欢
    • 2016-01-10
    • 2011-11-13
    • 2010-10-10
    • 1970-01-01
    • 1970-01-01
    • 2011-02-03
    • 2016-06-02
    • 1970-01-01
    • 2011-06-30
    相关资源
    最近更新 更多