软件的性能分析及调优时,往往需要了解函数的调用性能瓶颈和占用 CPU 耗时,linux perf工具用来分析软件性能,并借助火焰图(flame graph)查看函数的调用栈。

1. 安装perf

Ubutu默认没有安装perf,通过以下命令安装

1
2
sudo apt install linux-tools-common -y
sudo apt install linux-tools-generic linux-cloud-tools-generic -y

2. perf命令

1
sudo perf record -F 99 -p 6220 -g -- sleep 180

上面的代码中,perf record表示记录,-F 99表示频率,即每秒99次,-p表示进程pid,-g表示记录调用栈,-- sleep 180表示持续180s。

执行完成后,生成一个perf.data文件

1
sudo perf report -n --stdio

上面的代码将perf.data结果显示到终端,是不是可读性很差,于是有了火焰图.

perf-report-stdio.png

3. 火焰图

火焰图就是基于perf.data结果产出svg图,展示函数的调用栈。

1
2
3
4
5
6
# 下载火焰图生成工具
git clone https://github.com/brendangregg/FlameGraph.git
# 生成火焰图
sudo perf script -i perf.data &> perf.unfold
sudo FlameGraph/stackcollapse-perf.pl perf.unfold &> perf.folded
sudo FlameGraph/flamegraph.pl perf.folded > perf.svg

perf-svg-result.png

上图即为基于perf结果生成的火焰图。

Y轴表示函数的调用栈,每一层都是一个函数,调用的越深,火焰越高。顶部是正在执行的函数,下面是它的父函数。

X轴表示抽样数,如果一个函数在 x 轴占据的宽度越宽,就表示它被抽到的次数多,即执行的时间长。注意,x 轴不代表时间,而是所有的调用栈合并后,按字母顺序排列的。

火焰图就是看顶层的哪个函数占据的宽度最大。只要有"平顶”(plateaus),就表示该函数可能存在性能问题。

4. 互动性

火焰图是svg图片,支持互动。

  1. 鼠标悬浮时会显示完整的函数名、抽样抽中的次数、占据总抽样次数的百分比。
  2. 在某一层点击,火焰图会水平放大,该层会占据所有宽度,显示详细信息。
  3. 火焰图支持搜索,输入关键字或正则表达式,符合条件的结果会高亮显示。

5. 小结

本文使用linux perf工具分析程序性能,并使用FlameGraph生成火焰图,实际上火焰图的使用场景很多,深入研究可以参考火焰图官网

6. 参考

阮一峰的博客

火焰图官网