【问题标题】:How to iterate on the objects present in the .NET managed heap?如何迭代 .NET 托管堆中存在的对象?
【发布时间】:2009-02-12 05:02:34
【问题描述】:

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

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

【问题讨论】:

  • 请正确使用标记(托管堆而不是托管堆,垃圾收集器相同)。

标签: .net garbage-collection


【解决方案1】:
  1. 安装“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”。

  2. 运行您的托管进程。

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

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

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

  6. 在 WinDbg 的命令行中键入“.load sos.dll”(是的,使用前面的“.”)以加载“罢工之子”。

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

  8. 键入“!traverseheap –xml heap.xml”将进程的堆转储到 WinDbg 目录中的 heap.xml(例如,C:\Program Files\Debugging Tools for Windows")。

    一个。遍历堆并将其转储到文件可能需要非常非常长的时间。 WinDbg 会将“BUSY”发布到其状态并打印“.”-s 以指示进度。

    b.一般来说,heap.xml的结构如下:

    ...

    每个类(类型)都有一个 ID,每个对象都有它的类型 ID、托管地址和大小。

  9. 对 heap.xml 使用 findstr(命令提示符)以 grep 遍历堆,并使用 WinDbg 转储对象。

    一个。示例:查找 DataTable 类的类型 ID。

    • findstr "DataTable" heap.xml

      输出:

    b.示例:查找所有 DataTable 对象。

    • findstr "typeid=\"1002\"" heap.xml

      输出:

    c。示例:转储 DataTable 对象。

    • (在 WinDbg 中)!dumpobj 0137ecd8

    d。示例:转储成员对象。成员对象的地址存储在成员包含对象转储的“值”字段中。

    • !dumpobj

.

添加,如果您想跟踪大型对象分配,以下是如何在 LOH 分配上中断 CLR。中断时,按“k”查看调用堆栈。

运行WinDbg并附加如下。

  1. 将 Microsoft 的符号服务器添加到符号路径:
  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. 简历:
    • g

【讨论】:

    【解决方案2】:

    您需要使用 debugging/profiling API 来执行此操作 - 我不建议将其用于“普通”应用程序。

    【讨论】:

      猜你喜欢
      • 2011-02-25
      • 2014-09-28
      • 1970-01-01
      • 1970-01-01
      • 2010-09-06
      • 1970-01-01
      • 2012-07-27
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多