使用linux perf工具生成java程序火焰图
重要参考文献:
www.brendangregg.com/blog/2017-06-30/package-flame-graph.html
www.brendangregg.com/blog/2014-06-12/java-flame-graphs.html
Java FlameGraph(火焰图)能够非常直观的展示java程序的性能分析结果,方便发现程序热点和进一步调优。本文将展示如何使用linux perf工具生成java程序的火焰图。火焰图大致长这个样子:
http://www.brendangregg.com/blog/images/2014/cpu-vertx-flamegraph.svg
火焰图的横轴表示方法耗时百分比,某个方法占用横轴越长表示占用的CPU越多,纵轴表示函数调用关系,顶端表示调用的栈顶。
linux perf是一款linux下强大的性能分析工具。学习请参考:
https://www.ibm.com/developerworks/cn/linux/l-cn-perf1/index.html
http://www.brendangregg.com/perf.html
使用perf工具生成java程序的火焰图只需两步操作,体现在如下命令当中:
# sudo perf record -F 99 -a -- sleep 30; ./jmaps # sudo perf script | ./pkgsplit-perf.pl | grep java | ./flamegraph.pl > out.svg
第一步使用perf record收集程序运行时的堆栈信息;
第二部使用perf script生成分析结果,最终生成的out.svg文件就是火焰图。
上述命令中还用到了jmaps、pkgsplit-perf.pl、flamegraph.pl等脚本,这些脚本分类来自git项目https://github.com/brendangregg/FlameGraph。其中要着重说明的是jmaps脚本,该脚本的作用是获取java程序运行时的符号表,这样在执行perf script时才能生成有意义的堆栈信息,该脚本依赖git项目 https://github.com/jvm-profiling-tools/perf-map-agent,下载该项目成功编译后会在out目录下生成attach-main.jar和libperfmap.so两个文件,这是获取java程序运行时符号表的关键。打开jmaps文件,可以看到如下代码:
AGENT_HOME=${AGENT_HOME:-/usr/lib/jvm/perf-map-agent} # from https://github.com/jvm-profiling-tools/perf-map-agent
需要手动将AGENT_HOME替换为刚才编译后的per-map-agent/out/目录。
问题汇总:
perf-map-agent编译失败
perf-map-agent编译需要cmake和JDK,请现安装好cmake和JDK,并配置好JAVA_HOME。
执行./jmaps脚本出错,ERROR: not root user? exiting...
这是因为当前用户不是root, 直接注释掉jmaps脚本中的如下代码即可:
if [[ "$USER" != root ]]; then
echo "ERROR: not root user? exiting..."
exit
fi
执行./jmaps脚本出错,chown: changing ownership of '/tmp/perf-xxx.map': Operation not permitted
将jmaps中的代码
if [[ -e "$mapfile" ]]; then
chown root $mapfile
chmod 666 $mapfile
else
改为:
if [[ -e "$mapfile" ]]; then
sudo chown root $mapfile
sudo chmod 666 $mapfile
else
jmaps只能获取正在执行的java程序的符号表
使用jmaps获取java程序的符号表,仅限于正在运行的Java程序,一种情况是perf record时要监测的java程序还在运行,但等到执jmaps脚本时程序已经结束,则符号表获取会失败。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· AI 智能体引爆开源社区「GitHub 热点速览」
· 三行代码完成国际化适配,妙~啊~
· .NET Core 中如何实现缓存的预热?