如何用dotnet-trace分析.NET Core应用的真实CPU占用情况?
解决.NET Core应用CPU占用过高的真实CPU热点追踪问题
针对你遇到的dotnet-trace采集到挂钟时间(wall time)而非真实CPU时间的问题,可以通过以下几种方式追踪实际消耗CPU资源的函数:
1. 使用dotnet-trace内置CPU采样配置
直接使用--profile cpu参数启动采集,该配置专门针对**线程处于运行状态(占用CPU)**时进行采样,会自动过滤Sleep、WaitOne等空闲等待的栈信息:
dotnet-trace collect -p 1039 --profile cpu
生成的.nettrace文件在Visual Studio中打开后,切换到CPU时间统计视图,即可看到真正消耗CPU的函数热点。
2. 自定义EventPipe提供者参数
如果需要更精细的控制,可以直接指定System.Runtime的CPU采样事件,确保只采集线程运行时的栈:
dotnet-trace collect -p 1039 --providers System.Runtime:EventCounterIntervalSec=1,Microsoft-Windows-DotNETRuntime:0x1000:5
其中0x1000对应CPU采样事件(SampleProf),5是日志级别,该配置会忽略线程处于等待状态的采样数据。
3. 结合系统工具定位目标线程
在Ubuntu上先用htop或top -H找到占用CPU的具体线程ID(可通过dotnet-trace list-processes -p 1039查看进程内线程对应关系),然后针对该线程采样:
dotnet-trace collect -p 1039 --profile cpu --thread-id <目标线程ID>
这种方式可以缩小采样范围,更快定位到问题线程的CPU热点。
4. 使用dotnet-dump进行事后分析
如果CPU峰值出现时无法及时启动trace采集,可以先生成内存转储文件:
dotnet-dump collect -p 1039
然后用dotnet-dump analyze进入分析环境,执行以下命令查看CPU占用高的线程:
# 查看所有线程状态,找到State为Running的线程 threads # 查看指定线程的调用栈 clrstack -t <线程ID>
通过调用栈可以直接定位到正在执行的CPU密集型函数。
内容的提问来源于stack exchange,提问作者Shawn
相关产品推荐
相关产品推荐

