VisualStudio自带性能分析功能Diagnostics,但有时使用还是有局限,这时就需要Windows平台下的性能分析神器PerfView出场了。
1.PerfView下载
microsoft/perfview
2.PerfView使用
PerfView可以对计算机的CPU、内存等各类资源的使用情况进行监控。
下载PerfView.exe,双击运行。
点击“Collect>Collect”,可以看到采样界面。
可以将CPU的时钟采样间隔改为0.125,这样能得到更详细的采样结果。点击“Start Collection”按钮开始采集。同时启动并发请求,记录并发请求期间的堆栈调用情况。并发请求结束后停止采样,PerfView会自动压缩采样日志文件。
PerfView采集的日志还是很全面的,包括CPU栈、进程栈、磁盘IO栈、内存栈等。双击“CPU Stacks”可以看到采集到的所有进程,由于结果记录的是计算机运行的所有结果,只筛选需要进程进行查看。
选择“Flame Graph”查看这两个进程CPU资源占用的火焰图。可以看出在采样时间段内,两个进程在多并发条件下使用多线程进行处理,每个线程所消耗的时间能很清楚的看到。
3.火焰图使用
火焰图是基于 perf 结果产生的 SVG 图片,用来展示 CPU 的调用栈。
y 轴表示调用栈,每一层都是一个函数。调用栈越深,火焰就越高,顶部就是正在执行的函数,下方都是它的父函数。
x 轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。
火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶"(plateaus),就表示该函数可能存在性能问题 。
颜色没有特殊含义,因为火焰图表示的是 CPU 的繁忙程度,所以一般选择暖色调。
举个例子:
上面图片中,最顶层的函数g()占用 CPU 时间最多。d()的宽度最大,但是它直接耗用 CPU 的部分很少。b()和c()没有直接消耗 CPU。因此,如果要调查性能问题,首先应该调查g(),其次是i()。
另外,从图中可知a()有两个分支b()和h(),这表明a()里面可能有一个条件语句,而b()分支消耗的 CPU 大大高于h()。
我们可以将PerfView的采集日志导出为speed scope类型的json文件。通过speedscope网站(https://www.speedscope.app/)打开可以看到更详细的火焰图。speedscope的火焰图是倒着看的。
speedscope
将上一步的PerfView日志导出后在SpeedScope打开的效果如下:
可以很清楚的看到每个方法的调用情况,包括逻辑关系、使用时长等。
有了PerfVeiw和SpeedScope两大工具的辅助,对于性能问题的分析就可以更深一步了。
磨刀不误砍柴工