如何发现第0代堆中的可终结对象?

时间:2014-08-20 18:14:40

标签: c# garbage-collection windbg

我正在尝试追踪与垃圾收集相关的性能问题,其中一个症状是“Genized Finalization-Memory from Gen0”计数器显示了大量的对象,并且正在创建终结器并使其脱离每次Gen0收集后的第0代。

我如何发现这些物体是什么?

3 个答案:

答案 0 :(得分:6)

您可以使用带有SOS扩展名的WinDbg来查找Gen 0中的对象。

将WinDbg附加到您的.NET应用程序并加载SOS - 这是一个方便的提示,可在此处找到:

http://www.wintellect.com/blogs/jrobbins/automatically-load-the-right-sos-for-the-minidump

基本输入以下命令:

!analyze –v

这应该为您下载正确的SOS.DLL文件。如果失败,您可以运行以下两个命令:

.loadby sos clr

.loadby sos mscorwks

我忘了应该使用哪一个(如果.NET应用程序是.NET 4.0及更高版本,我认为你需要第一个),但尝试两者。接下来,尝试以下命令!dumpheap

!dumpheap -gen 0

这应该显示Gen 0中所有对象的列表。希望能帮到你。

编辑:

这是一段YouTube视频,展示了如何使用WinDbg调试.NET应用程序:

https://www.youtube.com/watch?v=yVzNrz1jJHU

答案 1 :(得分:3)

另一种方法是使用SOS提供的finalizequeue命令。这将显示所有已注册的对象以进行最终确定,而不仅仅是那些 ready 用于最终确定的对象:

0:010> !finalizequeue
SyncBlocks to be cleaned up: 0
Free-Threaded Interfaces to be released: 0
MTA Interfaces to be released: 0
STA Interfaces to be released: 0
----------------------------------
generation 0 has 33 finalizable objects (000000001b2b9710->000000001b2b9818)
generation 1 has 2 finalizable objects (000000001b2b9700->000000001b2b9710)
generation 2 has 580 finalizable objects (000000001b2b84e0->000000001b2b9700)
Ready for finalization 0 objects (000000001b2b9818->000000001b2b9818)
Statistics for all finalizable objects (including all objects ready for finalization):
              MT    Count    TotalSize Class Name
000007feebb95cb8        1           24 System.Threading.OverlappedDataCache
000007feebb81168        1           24 System.LocalDataStoreHolder
000007feebb14630        1           24 System.Threading.TimerHolder
000007feebb63a38        1           32 Microsoft.Win32.SafeHandles.SafePEFileHandle
000007feebb5ae38        1           32 Microsoft.Win32.SafeHandles.SafeFileMappingHandle
000007feebb5ada8        1           32 Microsoft.Win32.SafeHandles.SafeViewOfFileHandle
...<snip>...
Total 615 objects

然后你可以将所有对象转储到第1代内存范围内(因为它不具有包容性,所以剪掉了结尾)。在这里我只有两个,幸运的是:

0:010> dd 000000001b2b9700 000000001b2b9710-4
00000000`1b2b9700  02d51da0 00000000 02d51d50 00000000

然后将这些对象转储出来(这只是第一个):

0:010> !do 02d51da0 
Name:        System.WeakReference
MethodTable: 000007feebb6cbb0
EEClass:     000007feeb53f1d8
Size:        24(0x18) bytes
File:        C:\Windows\Microsoft.Net\assembly\GAC_64\mscorlib\v4.0_4.0.0.0__b77a5c561934e089\mscorlib.dll
Fields:
              MT    Field   Offset                 Type VT     Attr            Value Name
000007feebb6a338  4000688        8        System.IntPtr  1 instance           2128d8 m_handle

答案 2 :(得分:2)

您可以使用SOSEX的!finq命令列出每一代中的所有可终结对象。有关用法,请参阅SOSEX文档。