我最近开始使用蚂蚁分析工具进行生产工作。除了对他们的敬畏之情感到惊讶之外,我不禁想知道它们是如何工作的。例如,最有用的功能之一使您可以可视化运行程序的全局根,并包含对不同类型值的引用数量。

该工具如何掌握这些信息?

有帮助吗?

解决方案

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

您可以通过编写在要定位的过程中运行的CLR Profiler来做到这一点。 CLR剖面仪是C ++ com对象,当运行时实例化时 COR_PROFILERCOR_PROFILING_ENABLED 设置了环境变量(请参阅 这里)。有两个主要 CLR分析界面, , 具体来说, ICorProfilerCallbackICorProfilerInfo. ICorProfilerCallback 是CLR用来向您通知您有关您订阅的特定事件的通知(模块加载,函数jit补充,线程创建,GC事件),而 ICorProfilerInfo 您的参考器可以使用有关已加载的组件的线程,模块,类型,方法和元数据的其他信息。这个界面就是你 可以 用于获取有关分配类型的符号信息。

使用您的Profiler内部处理,您可以强行加入GC ICorProfilerInfo::ForceGC. 。 GC完成后,您的剖面人员将通过 ICorProfilerCallback2::GarbageCollectionFinished, ,您将通过 ICorProfilerCallback2::RootReferences2. 。当您将根参考信息与 ICorProfilerCallback::ObjectReferences, ,您可以获取.NET应用程序的完整对象参考图。

您可以通过使用 ICorProfilerCallback::ObjectAllocated 回调以确定何时创建单个CLR对象。但是,这可能很昂贵,因为您至少会为每个分配的对象引起至少一个附加功能调用。您可以通过映射CLR分配来跟踪单个对象 ObjectID 到您自己的内部ID。一个 ObjectID 对于给定的对象是短暂的指针,因为它可以随着垃圾收集的发生而改变,这可能会导致对象在压实过程中移动。说明了此过程 这里. 。您可以使用来自 ICorProfilerCallback::MovedReferences 跟踪移动对象。

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

David Broman是CLR Profiler的开发人员, 他的博客 总体上有大量有关分析的大量信息,包括您可能遇到的所有疯狂陷阱和问题。

其他提示

像蚂蚁这样的探查者使用CLR本身提出的“分析API”,这完全可以告诉您CLR内部发生了什么。例如,当对象分配,恰当地命名时发生API回调方法 纠纷(). 。同样,当输入方法,创建线程等时,也有一些事件。

原始分析API称为iCorprofilerCallback。后来的版本称为CoreProfilerCallback2和CoreProfilerCallback3。如果您搜索了这些名称,您会发现所需的答案。在Codeproject上,您可以看到一个实用的示例: 创建自定义.NET PROFILER

最后注意:API不能从托管代码(例如C#和vb.net)中使用。它仅可从不受管理的代码(例如C或C ++)获得。因此,C#应用程序无法使用此API来检查其自身的行为和对象。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top