关于dotnet-trace cpu-sampling及.NET Core高CPU排查的技术问询
.NET Core高CPU排查:
cpu-sampling采集的.nettrace分析指南 1. cpu-sampling模式下.nettrace包含的具体数据
- 定时采样的托管/非托管调用栈快照:默认每1ms采样一次(可配置),记录每个采样时刻各活跃线程的完整调用链
- 线程基础信息:线程ID、名称、状态(运行/等待等)、所属进程
- 时间戳与采样时序:每个快照对应的精确时间点,用于还原CPU使用率的时间分布
- .NET运行时核心事件:GC回收触发、JIT编译、线程池调度等关键运行时操作的记录
- 进程与模块信息:目标进程的ID、加载的.NET程序集、原生模块(如系统DLL)的路径与版本
2. 这些数据对排查高CPU根因的价值
- 调用栈快照:直接定位热点函数——CPU占比最高的函数/方法,快速缩小排查范围(比如某个业务循环、第三方库的计算逻辑)
- 线程状态分析:区分是真的CPU密集型计算(线程处于运行态),还是因锁竞争、IO等待导致的线程自旋(看似高CPU实则是无效等待)
- 运行时事件:排查是否由频繁GC(如内存泄漏导致的频繁Full GC)、JIT编译风暴(首次启动或动态编译过多代码)引发的高CPU
- 时序分布:定位高CPU的发生时段,结合业务场景关联是否有特定请求、定时任务触发
3. 分析数据的最佳工具与方法
工具选择
- Visual Studio性能探查器:直接加载
.nettrace,提供可视化的火焰图、调用树、热点列表,适合快速定位问题,对托管代码支持最友好 - PerfView:微软官方的高级性能分析工具,能深度解析
.nettrace的所有细节,包括非托管代码、GC、JIT等底层事件,适合复杂场景排查 - dotnet-trace命令行:用
dotnet-trace convert <trace-file> --format speedscope将.nettrace转为Speedscope格式,在浏览器中查看火焰图,轻量便捷
分析方法
- 先看全局CPU趋势:确认高CPU是持续存在还是间歇性爆发,对应到具体时间段
- 按CPU占比排序热点函数:优先关注Top 5的高占比函数,检查其调用链
- 区分托管/非托管代码:如果热点在非托管模块,需结合原生符号文件排查系统调用或第三方原生库问题
- 关联运行时事件:查看GC次数、JIT编译耗时,判断是否由运行时行为导致高CPU
- 检查线程并发:查看是否有大量线程同时执行同一逻辑,导致CPU核心被占满
4. 跨机器采集与分析的可行性
完全可以。.nettrace是自包含的二进制文件,采集完成后可直接拷贝到其他机器分析,无需依赖采集机器的.NET环境或业务代码。注意两点:
- 如果涉及非托管代码分析,最好将采集机器上的符号文件(.pdb)一并拷贝,或确保分析工具能通过符号服务器获取对应符号
- 分析机器只需安装对应的分析工具(Visual Studio、PerfView、dotnet-trace),无需部署目标应用
结果解读指导
- 火焰图解读:火焰图的横轴是采样次数(对应CPU占比),纵轴是调用栈深度,颜色越亮、宽度越宽的函数就是热点。点击函数可展开其调用链,看是谁在频繁调用它
- 调用树分析:查看函数的“独占CPU占比”(自身执行耗时)和“总CPU占比”(包括子函数耗时),如果独占占比高,说明函数本身有性能问题;如果总占比高,可能是被上层函数频繁调用
- GC相关排查:在PerfView或Visual Studio中查看GC事件的频率和耗时,如果Full GC频繁发生,结合内存快照排查内存泄漏
- 采样局限性注意:
cpu-sampling是基于时间间隔的采样,运行时间极短的函数可能被漏采,如果怀疑有这类问题,可改用更高采样频率,或使用cpu-profiling(事件追踪模式,无漏采但开销更高)
内容的提问来源于stack exchange,提问作者Zader
相关产品推荐
相关产品推荐

