.NET API 中是否有一种方法可以迭代托管堆中存在的托管对象?
我们想在程序的某些点添加一个例程,以检查托管堆中是否存在某些对象。
最佳答案
安装“Windows 调试工具”。
一个。链接:http://www.microsoft.com/whdc/devtools/debugging/default.mspx
您将使用 WinDbg.EXE( native Windows 调试器)和 SOS.DLL(又名“Son of Strike”),托管代码的 WinDbg 扩展。
默认安装位置是“C:\Program Files\Debugging Tools for Windows”。
运行您的托管流程。
运行 WinDbg 并单击“文件 -> 附加到进程...”
从列表中选择您的流程。
WinDbg 将在附加到您的进程时自动中断(停止)执行。
在 WinDbg 的命令行中键入“.load sos.dll”(是的,前面有“.”)以加载 Son of Strike。
键入“!help”以查看 Son of Strike 提供的命令/功能列表。
键入“!traverseheap –xml heap.xml”将进程的堆转储到 WinDbg 目录(例如,C:\Program Files\Debugging Tools for Windows)中的 heap.xml。
一个。遍历堆并将其转储到文件可能需要非常非常长的时间。 WinDbg 将发布“BUSY”到其状态并打印“.”-s 以指示进度。
一般来说,heap.xml 的结构如下:
< Type IDs >
...
< Objects >
Each class (type) holds an ID and each object holds its type ID, managed address, and size.
对 heap.xml 使用 findstr(命令提示符)在堆中进行 grep,并使用 WinDbg 转储对象。
一个。示例:查找 DataTable 类的类型 ID。
findstr "DataTable"heap.xml
Output: < type id="1002" name="System.Data.DataTable"/ >
示例:查找所有 DataTable 对象。
findstr "typeid=\"1002\""heap.xml
Output: < object address="0x0137ECD8" typeid="1002" size="296" >
示例:转储 DataTable 对象。
- (在 WinDbg 中)!dumpobj 0137ecd8
示例:转储成员对象。成员对象的地址存储在成员包含对象转储的“值”字段中。
- !dumpobj < "值">
.
补充一下,如果你想跟踪大对象分配,下面是如何在 CLR 中中断 LOH 分配。中断时,按“k”查看调用堆栈。
运行 WinDbg 并附加如下。
- 将微软的符号服务器添加到符号路径:
- .sympath srvc:\windows\symbols http://msdl.microsoft.com/download/symbols
- 重新加载符号:
- .重新加载
- 重新加载运行时 shim:
- .reload/f mscorwks.dll
- 中断 UP 分配:
- bp mscorwks!WKS::gc_heap::allocate_large_object
- 打破 MP 分配:
- bp mscorwks!SVR::gc_heap::allocate_large_object
- 确认断点:
- bl
- 简历:
- 克
关于.net - 如何迭代 .NET 托管堆中存在的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/487682/