从 GCSampledObjectAllocationHigh 转换 TypeId

9

我有一段代码使用了Microsoft.Diagnostics.Tracing.TraceEvent NuGet包,以下是我编写的代码:

using (var session = new TraceEventSession("mine"))
{
    session.StopOnDispose = true;

    session.EnableProvider(ClrTraceEventParser.ProviderGuid, TraceEventLevel.Verbose,
        (ulong)ulong.MaxValue,//,ClrTraceEventParser.Keywords.GCSampledObjectAllocationHigh,
        new TraceEventProviderOptions
        {
            StacksEnabled = true,
        });


    using (TraceLogEventSource traceLogSource = TraceLog.CreateFromTraceEventSession(session))
    {
        traceLogSource.Clr.GCSampledObjectAllocation += data =>
        {
            Console.WriteLine(data);
         };

        traceLogSource.Process();
    }
}

这会给我输出类似于这样的结果:
<Event 
    MSec="10355.9688" 
    PID="7056" 
    PName="" 
    TID="11468" 
    EventName="GC/SampledObjectAllocation" 
    Address="0x000000C780036870" 
    TypeID="0x00007FFF1EC60BD8" 
    ObjectCountForTypeSample="1" 
    TotalSizeForTypeSample="28" 
    ClrInstanceID="9" /> 

这段话已经很清楚了,有一个对象被分配了,其大小为28个字节。 然而,我不知道如何将TypeID映射到类型名称。

看起来像是这样可以实现我的需求:

traceLogSource.Clr.TypeBulkType += data =>
{
    for (int i = 0; i < data.Count; i++)
    {
        var e = data.Values(i);
        Console.WriteLine("{0} -> {1}", e.TypeID, e.TypeName);
    }
};

但我不知道如何从我正在检查的进程中触发其发送(可能是一个非常长时间运行的进程)。似乎仅在进程启动时(仅限观察)发送了批量类型,并且我找不到任何关于它们的文档。

有没有什么想法如何做到这一点?

1个回答

0

如果您查看TraceEvent中的ClrTraceEventParser.Keywords(您将找到GCHeapAndTypeNames位)。当您同时打开AllocationHigh位和此位时,每次首次注意到新类型时,它都应该发送BulkType事件。


如果您查看代码,您会发现我实际上是发送了 所有 标记(在这个测试案例中显然是如此)。 我的问题在于,我的代码试图检查一个长时间运行的服务器,因此我们谈论的所有类型都已经被加载。有没有一种方法可以强制它再次发送它们?或者其他获取 TypeId 和实际名称之间映射的方法? - Ayende Rahien

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接