跳转到主内容
新派编程网 - 新潮编程理念,全新技术课堂!

C#中dotnet-trace性能追踪_C#性能追踪采集教程【高级】

关键在采集时机、Provider配置和事件粒度匹配:默认附加跟踪不捕获JIT/GC事件,需显式指定Microsoft-Windows-DotNETRuntime:4:4等Provider;冷启动须用dotnet trace collect -- 同步采集;离线分析依赖PDB符号文件才能显示方法名。

直接用
dotnet-trace
采集性能数据,不等于就能定位到真实瓶颈——关键在采集时机、Provider 配置和事件粒度是否匹配问题场景。盲目全量采集只会生成超大
trace.nettrace
文件,反而掩盖热点。 对运行中进程附加跟踪时,为什么经常采不到 JIT 或 GC 事件? 默认
dotnet trace collect --process-id
启用的是基础运行时事件集,但 JIT 编译、GC 堆快照、ThreadPool 队列变化等关键事件需要显式启用对应 Provider。 必须加
--providers Microsoft-Windows-DotNETRuntime:4:4
才能捕获 GC 生命周期、代际提升、暂停时间等完整信息 JIT 相关事件(如方法编译、内联决策)需额外指定
Microsoft-Windows-DotNETRuntime-JIT:4:4
,否则只看到“Unknown Method”堆栈 Linux/macOS 上若想获取高精度 CPU 样本(非 wall-clock 时间),得用
Microsoft-DotNETCore-SampleProfiler:0x0000000000000001:4
,且进程需以
COMPlus_PerfMapEnabled=1
环境变量启动 Windows 上若目标进程是 .NET Framework 应用(非 .NET Core+),
dotnet-trace
完全不适用,得换
PerfView
或 ETW 工具 启动新进程时同步采集,如何避免漏掉冷启动阶段的关键事件? 冷启动阶段(如依赖注入容器构建、配置加载、静态构造函数执行)极易被忽略,因为默认采集从
dotnet trace collect
命令执行后才开始,而此时应用可能已初始化完毕。 C知道 CSDN推出的一款AI技术问答工具 下载 必须用
dotnet trace collect --
形式,而非先
dotnet run
再 attach——前者让
dotnet-trace
在子进程 fork 后立即注册 EventPipe 监听器 若应用有长耗时的初始化逻辑(如预热缓存、加载大模型),建议加
--duration 120
并手动触发业务动作后再结束采集,确保覆盖完整生命周期 不要依赖
dotnet run
默认的
Debug
模式编译结果——Release 模式下 JIT 行为、内联策略、调试符号剥离都会影响事件语义,PDB 缺失会导致方法名显示为
???
离线分析 trace.nettrace 时,Chrome Trace Format 转换为何有时看不到自定义方法?
dotnet trace convert
生成的
trace.json
是通用格式,但方法名解析严重依赖 PDB 文件和路径匹配。生产环境部署若未保留符号文件或路径变更,就会丢失上下文。 转换前确认当前目录存在与 trace 对应的
.pdb
文件,且文件名与 trace 中记录的模块名一致(如
MyApp.dll
对应
MyApp.pdb
) 若 trace 来自另一台机器,需把 PDB 复制到本地,并用
dotnet trace convert --symbols-dir ./symbols
显式指定符号路径 Chrome://tracing 中搜索方法名失败,优先检查 “Process Name” 列是否显示为
dotnet
而非你的应用名——这说明 Provider 没正确识别托管代码,大概率是没启用
Microsoft-Windows-DotNETRuntime
别指望
trace.json
显示 IL 或 JIT 汇编;它只还原托管调用栈。要看汇编级细节,得用
PerfView
打开原始
trace.nettrace
并启用 “View > Show Assembly” 真正难的不是采集,而是判断该开哪些 Provider、该信哪一列时间(Exclusive vs Inclusive)、以及怎么把一堆线程堆栈和 GC 暂停时间拼成一个可行动的优化结论。这些没法靠工具自动完成,得结合你代码里那几个关键
async
方法和
lock
块的位置来交叉验证。

相关文章