JAVA性能分析之使⽤⽕焰图
随着业务的发展,使⽤接⼝提供的服务的业务越来越多,不同的业务对调⽤耗时的要求不同,当然,耗时越少越好。⽽近来已经有三四个调
⽤⽅反映接⼝调⽤耗时太不稳定,代码上的优化已经做了很多,有效果,但还不够。同时,压⼒测试显⽰,复杂业务在调⽤量单机3000次/
分时CPU就已经100%了,与预期差距太远。为了改善接⼝性能,到性能瓶颈,不得已祭出了⼤杀器————⽕焰图。
⽹上的关于java⽕焰图的讲解⼤部分来⾃于,⽕焰图的效果⼤致如下图:
最终⽣成⼀个SVG格式的图⽚,图上的每个⾊块代表的是⼀个线程栈帧,纵轴⽅向从下往上表⽰的是函数调⽤栈,⽽横轴⽅向⾊块的宽度表
⽰的是函数调⽤占⽤CPU的⽐例。在使⽤Profiler对CPU进⾏采样时,根据CPU当前执⾏所处栈位置以及各个函数栈在总的采样次数所占⽐
例就可以得出各个函数执⾏时的CPU占⽤⽐例。
⽕焰图⽣成⽅式
⽕焰图的⽣成过程有两步:
1. 使⽤Profiler⼯具⽣成trace⽂件;
2. 将trace⽂件转换为svg格式的⽕焰图⽂件;
Brendan使⽤的Profiler是,这个需要⾃⼰编译:
make BITS=64 all
还可以通过更改global.h⽂件来配置采样次数:
// 每秒采样次数
static const int kNumInterrupts = 100;
// Maximum number of stack traces
static const int kMaxStackTraces = 3000;
/
/ 采样栈深度
static const int kMaxFramesToCapture = 128;
在长时间采样时,可以适当地减少每秒采样次数,不然最终⽣成的⽂件会很⼤,分析起来⽐较⿇烦。
编译⽣成⽂件liblagent.so,使⽤起来很简单,在java启动参数添加如下内容:
-agentpath:path/to/liblagent.so
java程序启动后会在当前⽬录⽣成⼀个⽂件,但⽂件中只有⼀些说明信息。程序正常结束(不是通过kill -9杀掉进程)后,才会写
⼊具体采样信息。
Brendan提供了⼀个来将各种Profiler⽣成的⽂件转化为⽕焰图svg格式。使⽤⽅式如下:
git clone github/brendangregg/FlameGraph
svg图片怎么使用cd FlameGraph
./stackcollapse-ljp.awk < ../ | ./flamegraph.pl > ../traces.svg
除了使⽤lightweight-java-profiler作为Profiler外,还有其他的选择,⽐如,lightweight-java-profiler会从java虚拟机启动开始采样,⽽
有时候我们需要在CPU飙⾼的时候开始,这时候honest-profiler提供的动态启停功能就有⽤武之地了。
使⽤honest-profiler⽣成⽕焰图:
⾸先,需要先或者honest-profiler,使⽤⽅式如下:
java -agentpath:/path/to/location/liblagent.so=interval=7,logPath=/path/to/output/log.hpl,start=0,host=127.0.0.1,port=12345 <normal-java-commandline
其中interval是采样频率,logPath表⽰⽣成的采样⽂件路径,start可取0或1,表⽰是否启动时就开启采样,host和port表⽰监听控制的IP
地址和端⼝号。
启动成功后,通过telnet连接到127.0.0.1:12345,即可通过命令控制采样的开始和结束。⽀持的命令包括:
start,开始采样
stop,停⽌采样
status,打印当前采样状态和采样⽂件⽬录
get [ParamName],获取参数值
set [ParamName] [ParamValue1] ….[ParamValueN] 设置参数值
[ParamName]可以是intervalMin, intervalMax, interval, maxFrames 或者 logPath
在⽣成log.hpl⽂件后,还需要通过其他⼯具才能转换为log.svg⽂件,当时是通过开源⼯具执⾏的这个过程。使⽤步骤如下:
git clone github/chengxiayan/hprof2flamegraph.git
cd hprof2flamegraph
python stackcollapse_hpl.py --discard-lineno --discard-thread log.hpl>log.hpl.output
./flamegraph.pl log.hpl.output>log.svg
其中python版本需要2.7以上,windows上安装了ActivePerl以后也可以通过执⾏
perl ./flamegraph.pl log.hpl.output>log.svg
来完成第⼆步转换过程。
关于采样⼯具的选取,可以看看⽂章 ,这⾥⾯列举了xprof,hprof,jprofile和yourkit四种采样器,并通过⼏个压测场景证明了这⼏种采样器的结果是相互⽭盾的。总结的原因有三点:
1. 采样器采样点不够随机,这⼏种采样器都只有在safe point采样;
2. 不同的采样器会注⼊不同的代码,从⽽影响程序优化过程,同时也影响了safe point的分布,进⼀步造成采样差异;
honest-profiler号称是避开了通过SUN/Oracle management agent去采样堆栈,⽽是使⽤⾃⼰实现的使⽤UNIX 操作系统信号和为Oracle Performance Studio 设计的内部API的sampling agent,从⽽提升了采样准确率。
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论