使用 perf + FlameGraph 生成火焰图(Flame Graph)笔记
- [使用 perf + FlameGraph 生成火焰图(Flame Graph)笔记](#使用 perf + FlameGraph 生成火焰图(Flame Graph)笔记)
-
- [一、什么是火焰图(Flame Graph)](#一、什么是火焰图(Flame Graph))
- 二、整体流程概览
- 三、准备环境
-
- [1️⃣ 安装 perf](#1️⃣ 安装 perf)
- [2️⃣ 下载 FlameGraph 工具](#2️⃣ 下载 FlameGraph 工具)
- [四、Step 1:使用 perf record 采样 CPU](#四、Step 1:使用 perf record 采样 CPU)
-
- [perf 是什么?](#perf 是什么?)
- 采样频率说明(99Hz)
- 示例命令
- 结束采样
- [五、Step 2:解析 perf.data(perf script)](#五、Step 2:解析 perf.data(perf script))
- [六、Step 3:折叠调用栈(stack collapse)](#六、Step 3:折叠调用栈(stack collapse))
- [七、Step 4:生成火焰图 SVG](#七、Step 4:生成火焰图 SVG)
- [八、Step 5:分析火焰图](#八、Step 5:分析火焰图)
- 九、常见问题与建议
-
- [1️⃣ 为什么一定要 `-g`?](#1️⃣ 为什么一定要
-g?) - [2️⃣ cpu-clock vs cycles](#2️⃣ cpu-clock vs cycles)
- [3️⃣ 生产环境是否安全?](#3️⃣ 生产环境是否安全?)
- [1️⃣ 为什么一定要 `-g`?](#1️⃣ 为什么一定要
- 十、总结
使用 perf + FlameGraph 生成火焰图(Flame Graph)笔记
参考项目: https://github.com/brendangregg/FlameGraph
适用场景:Linux 服务器 CPU 性能分析、热点函数定位、性能瓶颈排查
一、什么是火焰图(Flame Graph)
火焰图是一种 CPU 采样分析可视化图表,用于直观展示:
- 程序在 CPU 上花时间最多的函数
- 函数的 调用栈关系
- 哪些路径是性能瓶颈(Hot Path)
火焰图的核心含义
- 横轴(X 轴):CPU 时间占比(越宽表示耗时越多)
- 纵轴(Y 轴):调用栈深度(越高表示调用层级越深)
- 颜色:仅用于区分函数,无实际性能含义
🔥 顶部最宽的"平顶"函数,往往就是性能瓶颈
二、整体流程概览
生成火焰图通常分为 5 个步骤:
- 使用
perf record采集 CPU 采样数据 - 生成原始调用栈文本(
perf script) - 折叠调用栈(stack collapse)
- 生成 SVG 火焰图
- 用浏览器分析火焰图
流程示意:
perf record
↓
perf.data
↓
perf script
↓
perf.unfold
↓
stackcollapse-perf.pl
↓
perf.folded
↓
flamegraph.pl
↓
xxx.svg
三、准备环境
1️⃣ 安装 perf
perf 是 Linux 内核自带工具(kernel tools),执行 perf --version 查看版本,若不存在 perf 命令,则执行如下命令进行安装:
bash
yum install -y perf
# 或
dnf install -y perf
确认版本:
bash
perf --version
2️⃣ 下载 FlameGraph 工具
bash
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
主要会用到两个脚本:
stackcollapse-perf.plflamegraph.pl
四、Step 1:使用 perf record 采样 CPU
perf 是什么?
perf 是 Linux 原生性能分析工具(performance 的缩写),可以:
- 采集 CPU 正在执行的函数
- 记录函数调用栈(stack trace)
- 通过采样方式分析性能开销
采样频率说明(99Hz)
默认情况下:
- 每秒采样 99 次(99Hz)
- 如果 99 次采样都命中同一个函数
- 说明这一秒 CPU 几乎都在执行这个函数 👉 很可能是性能瓶颈
示例命令
bash
perf record -e cpu-clock -g -p 28591 -- sleep 60
参数解释:
| 参数 | 含义 |
|---|---|
-e cpu-clock |
以 CPU 时钟作为采样事件(通用、稳定) |
-g |
记录调用栈(非常关键) |
-p 28591 |
指定进程 PID(主 DN 进程号) |
sleep 60 |
持续采样 60 秒 |
⏱ 一般 30~60 秒 就足够定位 CPU 热点
结束采样
- 采样期间可以 Ctrl + C 提前结束
- 当前目录会生成文件:
text
perf.data
五、Step 2:解析 perf.data(perf script)
使用 perf script 将二进制采样数据转换为文本调用栈:
bash
perf script -i perf.data &> perf.unfold
输出说明
-
perf.unfold中包含:- 每一次采样的
- 完整函数调用栈(从栈顶到栈底)
示例(简化):
text
java
Interpreter
JVM_Invoke
syscall
六、Step 3:折叠调用栈(stack collapse)
火焰图要求将 相同调用路径进行合并统计。
执行命令
bash
./stackcollapse-perf.pl perf.unfold &> perf.folded
折叠后的格式
text
main;foo;bar 120
main;foo;baz 30
含义:
main → foo → bar这条调用路径- 被采样 120 次
七、Step 4:生成火焰图 SVG
bash
./flamegraph.pl perf.folded > cn.svg
生成结果:
cn.svg:标准火焰图文件
八、Step 5:分析火焰图
打开方式
- 直接用浏览器打开:
text
cn.svg
关键分析技巧
1️⃣ 找最宽的函数
- 宽度 = CPU 时间占比
- 越宽,越值得优化
2️⃣ 看"平顶山"
- 火焰图顶部的一大片函数
- 往往是性能瓶颈最终落点
3️⃣ 从下往上看调用路径
- 底部:入口函数(如 main / 线程函数)
- 顶部:最终耗 CPU 的函数
4️⃣ 使用搜索功能
- 点击右上角 🔍
- 输入函数名 / 模块名
九、常见问题与建议
1️⃣ 为什么一定要 -g?
- 没有
-g→ 只能看到函数耗时 - 有
-g→ 才能看到 调用链(根因分析)
2️⃣ cpu-clock vs cycles
| 事件 | 说明 |
|---|---|
| cpu-clock | 与 CPU 频率无关,推荐 |
| cycles | 与硬件相关,受频率影响 |
👉 通用分析优先用 cpu-clock
3️⃣ 生产环境是否安全?
- perf 属于 采样分析
- 对性能影响很小(通常 <5%)
- 适合线上问题定位(建议短时间)
十、总结
一句话总结:
perf 负责采样,FlameGraph 负责可视化,火焰图让 CPU 热点一眼可见。
核心命令回顾:
bash
perf record -e cpu-clock -g -p <PID> -- sleep 60
perf script -i perf.data &> perf.unfold
./stackcollapse-perf.pl perf.unfold &> perf.folded
./flamegraph.pl perf.folded > result.svg
若有转载,请标明出处:https://blog.csdn.net/CharlesYuangc/article/details/157093811