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

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

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

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

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

“为垃圾收集的对象提供枚举器。”

“由 [ ICorDebugGCReferenceEnum::Next方法 ] 填充的集合中的COR_GC_REFERENCE对象 表示三种对象:

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

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

  • 终结器队列中的对象。 终结器队列根源对象,直到终结器运行。“

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

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

如果要查看对象是否在最终化队列或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)

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

这里有一个很棒的教程