Appearance
火焰图生成指南
更新时间:2026-08-06
火焰图(Flame Graph)将 perf record 采样的函数调用栈可视化为一张交互式 SVG 图——横轴宽度 = 函数在采样中的占比,纵轴 = 调用深度,让你一眼看出程序的热点分布和调用关系。
关联:perf-record.md(采样)、perf-report.md(TUI 分析)
一、火焰图能回答什么问题
| 问题 | 火焰图中怎么看 |
|---|---|
| 哪个函数最占 CPU? | 顶部最宽的矩形 |
| 热点函数被谁调用的? | 矩形下方的"基座" |
| 热点函数调用了谁? | 矩形上方的"尖顶" |
| 有没有很深的调用链? | 纵轴深度 |
| 哪部分可以优化? | 又宽又高的"高原"区域 |
| 优化前后效果如何? | 两张火焰图并排对比宽度变化 |
二、前置准备
2.1 安装 FlameGraph 工具
bash
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph2.2 编译选项
要看到有意义的函数名(而非地址),必须:
bash
gcc -g -fno-omit-frame-pointer -O2 your_program.c -o your_program| 选项 | 作用 |
|---|---|
-g | 保留调试符号(函数名、行号) |
-fno-omit-frame-pointer | 保留帧指针,确保调用栈回溯准确 |
-O2 | 优化(生产环境真实性能) |
三、生成流程

Step 1:采样
bash
# 全系统采样 30 秒,99 Hz,记录调用栈
perf record -F 99 -g -a -- sleep 30
# 或针对特定进程
perf record -F 99 -g -p <pid> -- sleep 30
# 或运行命令
perf record -F 99 -g ./your_programStep 2:生成 perf script 输出
bash
perf script > perf.scriptStep 3:堆栈折叠
bash
./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded这一步将"每个样本一条调用链"折叠成"每种调用链→计数"格式。
Step 4:生成火焰图
bash
./FlameGraph/flamegraph.pl perf.folded > perf.svg四、火焰图类型
4.1 CPU 火焰图(默认)
bash
# 采样 CPU cycles
perf record -F 99 -g -a -- sleep 30
perf script > perf.script
./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded
./FlameGraph/flamegraph.pl perf.folded > perf.svg回答:"CPU 时间花在哪"。
4.2 内存火焰图
bash
# 采样 page-faults
perf record -e page-faults -g -a -- sleep 30
perf script > perf.script
./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded
./FlameGraph/flamegraph.pl --color=mem --countname="pages" perf.folded > perf_mem.svg4.3 关闭火焰图(Off-CPU)
bash
# 采样 sched:sched_switch(阻塞事件)
perf record -e sched:sched_switch -g -a -- sleep 30
perf script > perf.script
./FlameGraph/stackcollapse-perf.pl perf.script > perf.folded
./FlameGraph/flamegraph.pl --color=io --countname="us" perf.folded > perf_offcpu.svg回答:"程序在等什么"。
4.4 差分火焰图
bash
# 优化前采样 → perf_before.data
perf record -F 99 -g -o perf_before.data -- ./prog
perf script -i perf_before.data > before.script
./FlameGraph/stackcollapse-perf.pl before.script > before.folded
# 优化后采样 → perf_after.data
perf record -F 99 -g -o perf_after.data -- ./prog_opt
perf script -i perf_after.data > after.script
./FlameGraph/stackcollapse-perf.pl after.script > after.folded
# 差分火焰图(红色 = 增加,蓝色 = 减少)
./FlameGraph/difffolded.pl before.folded after.folded | \
./FlameGraph/flamegraph.pl > perf_diff.svg五、火焰图解读

| 视觉特征 | 含义 |
|---|---|
| 横轴宽度 | 该函数在采样中的占比(= CPU 时间占比) |
| 纵轴高度 | 调用栈深度(无关紧要,不代表开销) |
| 顶部平坦区 | 叶子函数,"宽"就是"慢" |
| 高原区 | 某个函数及其子调用整体开销大 |
| 尖塔 | 深度调用链,但单一子调用开销大 |
| 颜色 | 通常无特殊含义(默认随机),但差分图中红/蓝有意义 |
解读口诀
看顶部,找最宽的 → 这是热点。看热点下方的柱子 → 这是调用者,优化它收益最大。
六、常用 flamegraph.pl 选项
| 选项 | 含义 |
|---|---|
--color=java | Java 风格配色(绿色=Java,黄色=C++,红色=系统) |
--color=io | IO 风格配色(适合 Off-CPU 火焰图) |
--color=mem | 内存风格配色 |
--countname=<str> | 横轴单位名称(如 us, pages) |
--title=<str> | 图表标题 |
--width=<px> | 图像宽度(默认 1200) |
--reverse | 倒置火焰图(底部是叶子,顶部是根) |
--inverted | 冰柱图风格 |
七、perf record 火焰图采样参数建议
bash
# Brendan Gregg 推荐的标准火焰图采样
perf record -F 99 -g --call-graph fp -a -- sleep 30| 参数 | 原因 |
|---|---|
-F 99 | 避免与系统定时器(100 Hz)共振,且采样密度已足够统计意义 |
-g | 必须记录调用栈 |
--call-graph fp | 最快,但需要 -fno-omit-frame-pointer |
-a -- sleep 30 | 全系统 30 秒(覆盖程序完整运行周期) |
八、常见问题
Q: 火焰图里看不到函数名,全是地址?
A: 程序没有调试符号。重新编译加 -g,或确保未 strip 掉符号表。
Q: 调用栈中间断了?
A: 帧指针被优化掉了。加 -fno-omit-frame-pointer,或用 --call-graph dwarf(开销较大)。
Q: SVG 太大打不开?
A: 采样时间太长或采样频率太高。减少录制时间(10-30s),或用 --percent-limit 裁剪 perf.script。
九、与相关文档的交叉引用
| 场景 | 文档 |
|---|---|
| 学会采样 | perf-record.md |
| TUI 分析(不用火焰图) | perf-report.md |
| 汇编级分析 | perf-annotate.md |
| Off-CPU 分析(程序在等什么) | perf-sched.md |
| 实战案例 | perf 案例集 |
十、一句话总结
火焰图是性能分析的"热成像仪"——横轴 = 哪个函数最热,纵轴 = 调用关系全貌,一眼看清程序的 CPU 时间分布,是汇报性能结果和发现优化方向最直观的工具。