我一直试图在我的应用程序中修复内存泄漏.几个月前,我注意到在我的应用程序中,超过95%的对象被提升为Gen2; 我有一些非常基本的问题,我在书中找不到.我希望你们能帮助我:
先感谢您.
小智 13
有这么多Gen2对象是坏消息吗?
这不是坏消息.这可能意味着GC.Collect刚刚运行,或者它经常运行,并且你有足够的空闲内存 - 因此Gen2中的对象不会被收集.以下是另一个StackOverflow问题的一些很好的解释, 垃圾收集即使在需要时也没有发生:
启动垃圾收集时,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轻松转储特定代的对象.
以下是下载psscor2和psscor4 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
Run Code Online (Sandbox Code Playgroud)
当psscor这样做时,SOS没有简单的命令来转储特定代的对象.
使用此命令,您可以创建类似的结构
.foreach (obj { !dumpheap -gen 2 -short }) { !do ${obj} }
Run Code Online (Sandbox Code Playgroud)
要么
.foreach (obj { !dumpheap -gen 2 -type ExactTypeName -short }) { !gcroot ${obj} }
Run Code Online (Sandbox Code Playgroud)
找出第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
如果您仍然坚持一些步骤,请留下您的问题.
| 归档时间: |
|
| 查看次数: |
3096 次 |
| 最近记录: |