火焰图是怎么使用的?

你好,我是风一样的树懒,一个工作十多年的后端开发,曾就职京东、阿里等多家互联网头部企业。

点击下方👇关注公众号,带你一起复习后端技术,看看面试考点,补充积累技术知识,每天都为面试准备积累

文章可能会比较长,主要解析的非常详解,或涉及一些底层知识,供面试高阶难度用。可以根据自己实际理解情况合理取舍阅读


01
火焰图核心原理


1. 数据采集

通过 定时采样 记录程序调用栈,统计各函数在采样中的出现频率

2. 可视化规则

X轴:采样数量(越宽表示消耗越多CPU时间)

Y轴:调用栈深度(上层函数调用下层函数)

颜色:通常无特定含义,用于区分不同调用链

02
生成全流程(Linux环境)


1. 安装必备工具

# 安装perf和FlameGraph工具集sudo apt-get install linux-tools-common linux-tools-generic git clone https://github.com/brendangregg/FlameGraph.git


2. 采集性能数据

# 对进程进行采样(30秒)sudo perf record -F 99 -p <PID> -g -- sleep 30
# 生成原始数据文件sudo perf script > perf.data.out


3. 生成火焰图

# 转换数据格式FlameGraph/stackcollapse-perf.pl perf.data.out > perf.folded
# 生成SVG图形FlameGraph/flamegraph.pl perf.folded > flame.svg
03
Java专项火焰图


1. 使用Async-profiler(推荐)

# 下载工具wget https://github.com/jvm-profiling-tools/async-profiler/releases/download/v2.9/async-profiler-2.9-linux-x64.tar.gz
# 生成CPU火焰图./profiler.sh -d 30 -f /tmp/flame.svg <PID>
# 内存分配火焰图./profiler.sh -e alloc -d 60 -f alloc.svg <PID>


2. Arthas集成生成

# 启动Arthas后执行profiler start          # 开始采样profiler stop --format flamegraph > /tmp/flame.html  # 生成HTML格式


04
图形解读技巧


1. 分析模式识别

图形特征问题类型解决方案
平顶山单一函数高消耗优化热点函数算法
长条形阶梯深层调用链检查是否存在冗余调用
锯齿状边缘频繁短时函数调用考虑批量处理或缓存机制

2. 交互式分析

点击放大:查看具体函数调用细节

搜索框:按函数名过滤关键路径(如输入java过滤JVM内部调用)

05
实战案例解析


场景:某Java服务CPU使用率90%

1.生成火焰图
./profiler.sh -d 60 -f hotspot.svg 1234


2.代码优化  

该函数内部存在正则表达式回溯问题

优化正则表达式为^[A-Z0-9]{8}$,CPU下降至40%


06
高级使用技巧


1. 差分火焰图

# 对比两个时间点的性能差异./profiler.sh -d 30 -f base.svg <PID># 执行压测后再次采样./profiler.sh -d 30 -f new.svg <PID># 生成差分图difffolded.pl base.svg new.svg | flamegraph.pl > diff.svg

2. 内存泄漏分析

# 跟踪内存分配./profiler.sh -e alloc -d 300 -f alloc.svg <PID>


07
注意事项


1.采样时间:生产环境建议至少采样30秒(避免偶然性)

2.符号表:确保保留调试符号(Java需保留-g编译参数)

3.容器环境:需挂载/sys/kernel/debug并开启perf_event_open

4.安全权限:部分操作需要CAP_PERFMON或root权限


通过火焰图可以快速定位以下典型问题:

代码热点:消耗大量CPU的函数

锁竞争:显示在monitorenter/park()的堆积

IO瓶颈:在read/write系统调用处出现宽条

内存问题:分配路径上出现异常高频调用

建议将火焰图生成流程封装为监控系统的自动诊断模块,实现:
告警触发 -> 自动采样 -> 图形生成 -> 归档分析 的完整闭环。


今天的内容就分享到这儿,喜欢的朋友可以关注,点赞。有什么不足的地方欢迎留言指出,您的关注是我前进的动力!

END


扫码关注

一起积累后端知识
不积跬步,无以至千里
不积小流,无以成江海

喜欢此内容的人还喜欢

《Java面试题指南》回归啦~


一个阿里二面面试官必问的问题


Lambda表达式说爱你不容易


分享面试:mysql数据库索引失效的情况


Spring-Boot中一个不起眼的好工具StopWatch