.net - 如何迭代 .NET 托管堆中存在的对象?

标签 .net garbage-collection

.NET API 中是否有一种方法可以迭代托管堆中存在的托管对象?

我们想在程序的某些点添加一个例程,以检查托管堆中是否存在某些对象。

最佳答案

  1. 安装“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”。

  2. 运行您的托管流程。

  3. 运行 WinDbg 并单击“文件 -> 附加到进程...”

  4. 从列表中选择您的流程。

  5. WinDbg 将在附加到您的进程时自动中断(停止)执行。

  6. 在 WinDbg 的命令行中键入“.load sos.dll”(是的,前面有“.”)以加载 Son of Strike。

  7. 键入“!help”以查看 Son of Strike 提供的命令/功能列表。

  8. 键入“!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.

  9. 对 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 并附加如下。

  1. 将微软的符号服务器添加到符号路径:
  2. 重新加载符号:
    • .重新加载
  3. 重新加载运行时 shim:
    • .reload/f mscorwks.dll
  4. 中断 UP 分配:
    • bp mscorwks!WKS::gc_heap::allocate_large_object
  5. 打破 MP 分配:
    • bp mscorwks!SVR::gc_heap::allocate_large_object
  6. 确认断点:
    • bl
  7. 简历:

关于.net - 如何迭代 .NET 托管堆中存在的对象?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/487682/

相关文章:

c# - 强制执行方法

.net - 在 app.config 中管理多个客户端端点配置(IP 地址等)的最佳方法

c++ - 原始变量是否在 C++ 中被垃圾收集

c# - 既然 .NET 有一个垃圾收集器,为什么我们需要终结器/析构器/dispose-pattern?

.net - 为什么 .NET 3.5 垃圾收集器卡住我的应用程序?

.NET 内存泄漏?

c# - 如何列出所有月份名称,例如组合?

c# - MSBUILD 引发错误 : The SDK 'Microsoft.NET.Sdk' specified could not be found

java - 垃圾收集 - 为什么 c3 在此示例中不符合收集条件 (SCJP 6)

python - 如何删除包含其绑定(bind)方法列表的对象