.net应用程序对象升级为第2代

时间:2012-08-03 13:14:01

标签: c# .net windbg

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

  1. 有这么多Gen2对象是坏消息吗?在我拍摄的每个快照中,我在WinDbg中获得77,000个Gen2对象,100个Gen1对象和10个Gen0对象。
  2. 我怎样才能找到这么多对象升级的原因?有一个好工具吗?我一直在使用WinDbg / SOS而且运气不好
  3. 提前谢谢。

1 个答案:

答案 0 :(得分:13)

  

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

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

  
    

启动垃圾收集时,GC确定需要收集哪些代(0,0 + 1或全部)。每一代都有一个由GC确定的大小(它可以随着应用程序的运行而改变)。如果只有第0代将超过其预算,那么这是唯一将收集垃圾的一代。如果在第0代中存活的对象将导致第1代超过其预算,那么第1代也将被收集,其幸存的对象将被提升为第2代(这是Microsoft实现中的最高代)。如果超过第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的文件夹中。 dll的86版本x86文件夹(C:\程序文件(x86)\ Windows调试工具),动态链接库的64位版本的x64文件夹(C:\ Program Files文件\ Windows调试工具(64))。

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

    !dumpheap -gen 2

当psscor这样做时,SOS没有简单的命令来转储特定代的对象。

使用此命令,您可以创建

之类的结构
.foreach (obj { !dumpheap -gen 2 -short }) { !do ${obj} }

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

找出gen 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

如果你仍然坚持一步,请留下你的问题。