【问题标题】:Obtaining global roots from .NET programs从 .NET 程序中获取全局根
【发布时间】:2010-10-09 22:12:21
【问题描述】:

我最近开始使用 ANTS 分析工具进行生产工作。除了对它们的出色表现感到惊讶之外,我不禁想知道它们是如何工作的。例如,最有用的功能之一是让您可视化正在运行的程序的全局根,以及对不同类型值的引用数量。

此工具如何获取这些信息?

【问题讨论】:

    标签: c# .net f# profiling ants


    【解决方案1】:

    (完全披露:我在 Visual Studio Profiler 团队,但以下信息是公开的)

    您可以通过编写一个在您的目标进程内运行的 CLR 分析器来做到这一点。 CLR 分析器是 C++ COM 对象,当设置 COR_PROFILERCOR_PROFILING_ENABLED 环境变量时,运行时会实例化它们(请参阅 here)。有两个主要的CLR profiling interfaces,具体来说,ICorProfilerCallbackICorProfilerInfoICorProfilerCallback 是 CLR 用来通知您订阅的特定事件(模块加载、函数 JIT 编译、线程创建、GC 事件),而您的分析器可以使用 ICorProfilerInfo 来获取有关线程的其他信息,加载程序集的模块、类型、方法和元数据。您可以使用此接口获取有关分配类型的符号信息。

    使用您的分析器进行中,您可以通过ICorProfilerInfo::ForceGC 强制进行 GC。 GC 完成后,您的分析器将通过ICorProfilerCallback2::GarbageCollectionFinished 收到通知,您将通过ICorProfilerCallback2::RootReferences2 获得根引用。当您将根引用信息与ICorProfilerCallback::ObjectReferences 结合时,您可以获得.NET 应用程序的完整对象引用图。

    您可以通过使用ICorProfilerCallback::ObjectAllocated 回调来确定何时创建各个CLR 对象来获取更多实时信息。但是,这可能会很昂贵,因为您至少会为每个分配的对象产生一个额外的函数调用。您可以通过将 CLR 分配的 ObjectID 映射到您自己的内部 ID 来跟踪单个对象。给定对象的ObjectID 是一个临时指针,因为它可以随着垃圾回收的发生而改变,这可能导致对象在压缩期间移动。这个过程在here 中说明。您可以使用来自ICorProfilerCallback::MovedReferences 的信息来跟踪移动的物体。

    为了激活上述回调,您需要告诉 CLR 分析 API 您对它们感兴趣。您可以通过在调用 ICorProfilingInfo::SetEventMask 时指定 COR_PRF_MONITOR_GCCOR_PRF_MONITOR_OBJECT_ALLOCATED 作为事件标志的一部分来做到这一点。

    David Broman 是 CLR 分析器的开发人员,his blog 拥有大量关于一般分析的重要信息,包括您可能遇到的所有疯狂陷阱和问题。

    【讨论】:

      【解决方案2】:

      像 ANTS 这样的分析器使用 CLR 本身提供的“分析 API”,它可以很简单地告诉您 CLR 内部发生了什么。例如,在分配对象时会发生一个 API 回调方法,恰当地命名为ObjectAllocated()。同样,当输入方法、创建线程等时也会发生事件。

      原始分析 API 称为 ICorProfilerCallback。更高版本称为 CoreProfilerCallback2 和 CoreProfilerCallback3。如果你用谷歌搜索这些名字,你会找到你正在寻找的答案。在 codeproject 你可以看到一个实际的例子:Creating a Custom .NET Profiler

      最后一点:不能在 C# 和 VB.NET 等托管代码中使用 API。它仅适用于非托管代码,例如C 或 C++。因此,例如,C# 应用程序不能使用此 API 来检查自己的行为和对象。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2018-01-16
        • 2020-08-14
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2015-07-08
        • 1970-01-01
        • 2013-06-12
        相关资源
        最近更新 更多