如何在GC完成列表中列出所有对象?

时间:2015-05-20 10:28:32

标签: c# garbage-collection finalization

我的程序崩溃了,它是VS的可视化工具,因此,它很难调试,我试图进行转储并使用WinDbg来研究它,但它不成功。

所以,现在我尝试以编程方式将手放在该列表上,但我不知道如何。感谢。

2 个答案:

答案 0 :(得分:3)

如果要查看对象是否在终结队列或f-reachable队列中,当您启动WinDBG时,首先使用dumpheap -stat或任何其他命令找到您的对象。找到对象地址后,您可以使用!FinalizeQueue输出每一代中可确定的对象数量,以及准备完成的对象数 。前者是终结队列,后者是f-reachable队列。

例如:

  

0:003> !FinalizeQueue

     

要清理的SyncBlocks:0 MTA接口   待发布:0个要发布的STA接口:0

     

第0代有370个可终结的对象
  (0000000000d29030-> 0000000000d29bc0)

     

第1代有4个可终结的对象
  (0000000000d29010-> 0000000000d29030)

     

第2代有8个可终结的对象
  (0000000000d28fd0-> 0000000000d29010)

     

准备完成571个对象
  的(0000000000d29bc0-> 0000000000d2ad98)

现在,您可以看到对象地址空间的位置。

一个很棒的教程是available here

答案 1 :(得分:2)

我认为没有办法通过.NET的托管框架类库(FCL)进入终结队列。我怀疑如果你想以编程方式而不是debugging with WinDbg这样做,你(就像WinDbg和类似工具一样)将需要使用CLR的非托管调试&为此目的分析API。

看看ICORDebugGCReferenceEnum COM interface。您可以通过ICorDebugProcess5::EnumerateGCReferences检索该类型的对象:

  

"为将被垃圾收集的对象提供枚举器。"

     

" [COR_GC_REFERENCE] 填充的集合中的ICorDebugGCReferenceEnum::Next method个对象代表三种对象:

     
      
  • 来自所有托管堆栈的对象。这包括托管代码中的实时引用以及公共语言运行库创建的对象。

  •   
  • 来自句柄表的对象。这包括强引用(HNDTYPE_STRONGHNDTYPE_REFCOUNT)和模块中的静态变量。

  •   
  • 终结器队列中的对象。终结器队列根目标对象,直到终结器运行。"

  •   
     

(我添加了超链接和重点。)

枚举器返回的每个对象都有一个字段type。您可能希望过滤该字段与值CorGCReferenceType.CorReferenceFinalizer匹配的对象。