async-profiler采样分析器(可生成火焰图)
1 概述
async-profiler是一个低开销的Java运行时采样分析器(不进入安全点,不造成应用停顿),它依赖Hotspots的特定API AsyncGetCallTrace, 配合Linux perf_events机制,异步采集热点方法调用栈(包括Java方法,JVM Native方法与系统调用)的相关信息。
追踪的事件类型包括:
1、CPU处理周期时间
2、在Java堆的内存分配信息,锁信息 3、Linux性能计数器,比如上下文切换次数,cache失效次数、分支预测失败次数、缺页中断次数等等
2 使用说明
2.1 下载并解压
Zip包, 点击zip文件的Artifact Information
Tab,下载并解压。
RPM包, 安装在/apps/sh/tools/vjtools/aysnc-profiler
2.2 内核参数配置
下面两个内核参数必须正确配置,否则数据不能采集,可先用 cat /proc/sys/kernel/perf_event_paranoid
检查
# [必选]将perf_event_paranoid设为1,表示内核与用户空间的性能计数器都可以访问。
[root@server1]# echo 1 > /proc/sys/kernel/perf_event_paranoid
# 将kptr_restrict设为0,表示不限制内核指针
[root@server1]# echo 0 > /proc/sys/kernel/kptr_restrict
如果上述参数无法修改,请改为使用-e itimer 降级模式(见2.6.5)。
2.3 运行前提
执行profiler脚本的用户,必须与启动目标JVM进程的用户相同,或者Root用户。
尽量让应用运行一段时间,对代码充分JIT编译之后,再进行采集,否则采集的并不是JIT后的真正热点代码,在采集过程中发生JIT更加会造成混乱。
有条件的话,确保目标应用增加启动参数-XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints
, 结果将更加精确,否则内联的方法将不出现在结果里。
2.4 执行命令
# 进入async-profiler目录,
# RPM包标准安装的/apps/sh/tools/vjtools/async-profiler
# 压缩包安装进入到压缩目录
# 默认采集cpu信息,默认采集间隔10ms
# -d 60 采集数据的时间为60秒,60秒之后自动停止
# -f /tmp/flamegraph.svg 数据输出到指定目录下的火焰图中,最好用绝对路径指定,相对路径的话,文件会生成在目标程序的运行目录里。
# 13625是pid进程号
[root@server1]# ./profiler.sh -d 60 -f /tmp/flamegraph.svg 13625
2.5 火焰图观看
flamegraph.svg文件可以用火狐或谷歌等浏览器打开(可以把文件直接拖进浏览器)
纵向从下至上,代表方法间的调用关系,横条的宽度代表所占CPU时间的多少,
绿色代表java方法,浅绿色代表被内联的java方法,黄色代表jvm的c++方法,红色代表jvm其他native方法,褐色代表Linux内核调用
可以点击任何横条导航可以drilldown,点击左上角reset
点击右上角search,可以搜素关心的方法
如何读懂火焰图,这篇文章写得很好:http://www.ruanyifeng.com/blog/2017/09/flame-graph.html
2.6 其他命令
1.输出为类似传统jprofiler,jmc格式的树状结构的html
[root@server1]# ./profiler.sh -d 60 -f /tmp/flamegraph.html 13625
2.火焰图倒置,如果要看哪个最终方法占用的CPU最多,聚合它被其他各个方法调用的总和
[root@server1]# ./profiler.sh --reverse -d 60 -f /tmp/flamegraph-reverse.svg 13625
3.每条线程一幅火焰图,如果只关心某些特定线程里的消耗。
[root@server1]# ./profiler.sh -t -d 60 -f /tmp/flamegraph-reverse.svg 13625
4.耗时跟踪
默认按CPU消耗分析,如果方法在等待远程调用,数据库返回的阶段,不会统计在内。而耗时跟踪会更适合于找慢调用的情况。
官方文档推荐分开每条线程统计,而且将采样间隔从默认10ms降到5ms。
[root@server1]# ./profiler.sh -e wall -t -i 5ms -d 60 -f /tmp/flamegraph-reverse.svg 13625
5.纯java方法的cpu消耗跟踪
如果内核参数不符合又无法改变,那cpu模式可以降级为itimer模式,不读取perf_event,仅采集java方法,不采集内核调用
[root@server1]# ./profiler.sh -e itimer -d 60 -f /tmp/flamegraph-reverse.svg 13625
6.内存分配跟踪
[root@server1]# ./profiler.sh -e alloc -d 60 -f /tmp/flamegraph-reverse.svg 13625
7.锁跟踪
最新版的master snapshot版支持JDK7/8(目前生产版本) , 旧版crash in JDK7 !!!!
[root@server1]# ./profiler.sh -e lock -d 60 -f /tmp/flamegraph-reverse.svg 13625
8.ContextSwitch 及更多跟踪
[root@server1]# ./profiler.sh -e context-switches -d 60 -f /tmp/flamegraph-reverse.svg 13625
其他可选监控,执行
[root@server1]# ./profiler.sh list 13625