4

我的程序崩溃了,它是 VS 的可视化工具,所以调试起来非常困难,我尝试制作转储并使用 WinDbg 研究它,但没有成功。

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

4

2 回答 2

3

如果您想查看一个对象是否在终结队列或 f-reachable 队列中,当您启动 WinDBG 时,首先使用dumpheap -stat或任何其他命令定位您的对象。找到对象地址后,可以使用!FinalizeQueuewhich 将输出每一代中有多少对象是可终结的,以及有多少对象准备好进行终结。前者是finalization queue,后者是f-reachable queue。

例如:

0:003> !FinalizeQueue

要清理的同步块:0 MTA 要释放的接口:0 要释放的 STA 接口:0

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

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

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

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

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

这里有一个很棒的教程

于 2015-05-20T10:56:59.153 回答
2

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

看看ICORDebugGCReferenceEnumCOM接口。您可以通过以下方式检索该类型的对象ICorDebugProcess5::EnumerateGCReferences

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

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

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

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

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

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

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

于 2015-05-20T10:56:09.100 回答