【发布时间】:2009-02-12 05:02:34
【问题描述】:
.NET API 中有没有一种方法可以迭代托管堆中存在的托管对象?
我们想在程序的某些点添加一个例程,用于检查托管堆中某些对象的存在。
【问题讨论】:
-
请正确使用标记(托管堆而不是托管堆,垃圾收集器相同)。
.NET API 中有没有一种方法可以迭代托管堆中存在的托管对象?
我们想在程序的某些点添加一个例程,用于检查托管堆中某些对象的存在。
【问题讨论】:
安装“Windows 调试工具”。
一个。链接:http://www.microsoft.com/whdc/devtools/debugging/default.mspx
b.您将使用本机 Windows 调试器 WinDbg.EXE 和托管代码的 WinDbg 扩展 SOS.DLL(又名“罢工之子”)。
c。默认安装位置是“C:\Program Files\Debugging Tools for Windows”。
运行您的托管进程。
运行 WinDbg 并单击“文件 -> 附加到进程...”
从列表中选择您的进程。
WinDbg 将在附加到您的进程时自动中断(停止)执行。
在 WinDbg 的命令行中键入“.load sos.dll”(是的,使用前面的“.”)以加载“罢工之子”。
键入“!help”以查看 Son of Strike 提供的命令/功能列表。
键入“!traverseheap –xml heap.xml”将进程的堆转储到 WinDbg 目录中的 heap.xml(例如,C:\Program Files\Debugging Tools for Windows")。
一个。遍历堆并将其转储到文件可能需要非常非常长的时间。 WinDbg 会将“BUSY”发布到其状态并打印“.”-s 以指示进度。
b.一般来说,heap.xml的结构如下:
...
每个类(类型)都有一个 ID,每个对象都有它的类型 ID、托管地址和大小。
对 heap.xml 使用 findstr(命令提示符)以 grep 遍历堆,并使用 WinDbg 转储对象。
一个。示例:查找 DataTable 类的类型 ID。
findstr "DataTable" heap.xml
输出:
b.示例:查找所有 DataTable 对象。
findstr "typeid=\"1002\"" heap.xml
输出:
c。示例:转储 DataTable 对象。
d。示例:转储成员对象。成员对象的地址存储在成员包含对象转储的“值”字段中。
.
添加,如果您想跟踪大型对象分配,以下是如何在 LOH 分配上中断 CLR。中断时,按“k”查看调用堆栈。
运行WinDbg并附加如下。
【讨论】:
您需要使用 debugging/profiling API 来执行此操作 - 我不建议将其用于“普通”应用程序。
【讨论】: