【问题标题】:Translating TypeId from GCSampledObjectAllocationHigh从 GCSampledObjectAllocationHigh 转换 TypeId
【发布时间】:2025-12-09 11:20:03
【问题描述】:

我有使用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);
    }
};

但我不知道如何从我正在检查的进程中触发它的发送(这可能是一个运行时间很长的进程)。批量类型似乎只在进程开始时发送(仅限观察),我在它们上找不到任何文档。

有什么想法吗?

【问题讨论】:

    标签: profiling etw


    【解决方案1】:

    如果您查看 TraceEvent 中的 ClrTraceEventParser.Keywords(您会发现 GCHeapAndTypeNames 位)。当您打开它以及 AllocationHigh 位时,每次第一次注意到一个新类型时,它都应该发送一个 BulkType 事件。

    【讨论】:

    • 如果你看一下代码,我实际上是在发送 all 标志(在这个测试用例中,很明显)。我的问题是我的代码正在尝试检查一个长时间运行的服务器,所以我们讨论的所有类型都已经加载了。有没有办法诱导它再次发送它们?或者其他方式来获取 TypeId 和实际名称之间的映射?