🔥 火焰图(Flame Graph) 是一种可视化性能分析工具,可以帮助你快速定位 CPU、内存或 I/O 瓶颈。它看起来像火焰,因此得名。
- 火焰图能解决什么问题?
- CPU 占用高:找出哪些函数消耗了最多的 CPU 时间。
- 程序卡顿:分析代码执行路径,找到慢速操作。
- 线程阻塞:查看哪些线程在等待锁或 I/O。
- 内存泄漏(需配合内存分析工具)。
- 准备工作
Linux / macOS
安装 perf(Linux 性能分析工具)
sudo apt install linux-tools-common linux-tools-generic # Ubuntu/Debian
sudo yum install perf # CentOS/RHEL
安装 FlameGraph 脚本
git clone https://github.com/brendangregg/FlameGraph.git
cd FlameGraph
export PATH=PATH:(pwd) # 临时添加到 PATH
- 生成 CPU 火焰图(以 Java 为例)
(1)采集数据
方法 1:使用 perf(推荐,适用于 Linux)
1. 找到 Java 进程 ID
jps # 或 ps -ef | grep java
2. 采集 CPU 调用栈(采样 30 秒)
sudo perf record -F 99 -p -g -- sleep 30
3. 生成火焰图
perf script | stackcollapse-perf.pl | flamegraph.pl > flamegraph.svg
方法 2:使用 async-profiler(更简单,支持 Java)
下载 async-profiler
tar -xzf async-profiler-.tar.gz
cd async-profiler-
采集 CPU 数据(采样 30 秒)
./profiler.sh -d 30 -f flamegraph.svg
(2)查看火焰图
生成的 flamegraph.svg 可以用浏览器打开:
firefox flamegraph.svg # 或 chrome, edge
4. 如何读懂火焰图?
火焰图结构
- Y 轴(高度):调用栈深度(越深表示调用链越长)。
- X 轴(宽度):函数执行时间占比(越宽表示占用 CPU 越多)。
- 颜色:无特殊含义,仅用于区分不同函数。
关键操作
操作
说明
鼠标悬停
显示函数名、CPU 占比
点击放大
查看某个函数的详细调用链
搜索(Ctrl+F)
查找特定函数(如 java.lang.Thread.sleep)图片
- 常见问题
(1)火焰图显示 [unknown] 怎么办?
- 原因:缺少调试符号(如 JVM 未启用 -XX:+PreserveFramePointer)。
- 解决方案:
Java 运行时添加参数
java -XX:+PreserveFramePointer -jar your_app.jar
或者使用 async-profiler 的 --all-user 选项
./profiler.sh --all-user -d 30 -f flamegraph.svg
(2)如何分析内存泄漏?
改用 内存火焰图(需 async-profiler):
./profiler.sh -d 30 -e alloc -f mem_flamegraph.svg
6. 进阶用法
场景
命令
分析锁竞争
./profiler.sh -e lock -d 30 -f lock.svg
分析 I/O 等待
perf record -e 'sched:sched_stat_iowait' -p -g -- sleep 10
生成差分火焰图
diff two_flamegraphs.svg
7. 总结
- 安装工具:perf + FlameGraph 或 async-profiler。
- 采集数据:perf record 或 ./profiler.sh -d 30。
- 生成 SVG:flamegraph.pl 转换数据。