java性能分析工具-async-profiler
介绍
Async-profiler是一个对系统性能影响很少的Java采样分析器,它的实现是基于HotSpot特有的API,通过这些特有的API收集堆栈跟踪和跟踪内存分配,因而其可以和OpenJDK、Oracle JDK和其他基于HotSpot JVM的Java应用在运行时协同工作。
Github项目链接地址:https://github.com/jvm-profiling-tools/async-profiler
环境准备
首先,你需要从github将代码下载下来:
git clone https://github.com/jvm-profiling-tools/async-profiler
然后,进入到下载好的项目中,然后进行编译:
cd async-profiler
make
可以发现在async-profiler项目中有一个脚本叫做“profiler.sh”,运行这个脚本,会输出如下提示内容:
其中几个重要的命令解释如下:
start : 开始进行应用的profile数据采集,如果没有设定采集时间的话会一直运行下去直到遇到stop命令
stop: 和start配合使用,用来停止应用的profile数据采集
status:检测工具的运行状态,比如可以看到是否已经不可用,或者已经运行多少时间了等信息
list:将可以采集的profile数据类型打印出来
-d N: 设定采集应用profile数据的时间,单位为秒
-e event:指定采集数据类型,比如cpu
下面来开始使用async-profiler工具来采集cpu profile数据,并且配合火焰图生成工具工具FlameGraph来生成cpu火焰图,并且从火焰图中找到热点代码。FlameGraph工具可以直接下载下来就可以使用:
git clone https://github.com/brendangregg/FlameGraph
首先将java应用运行起来,你可以试着运行下面的代码来进行测试:
import java.io.File;
class Target {
private static volatile int value;
private static void method1() {
for (int i = 0; i < 1000000; ++i)
++value;
}
private static void method2() {
for (int i = 0; i < 1000000; ++i)
++value;
}
private static void method3() throws Exception {
for (int i = 0; i < 1000; ++i) {
for (String s : new File("/tmp").list()) {
value += s.hashCode();
}
}
}
public static void main(String[] args) throws Exception {
while (true) {
method1();
method2();
method3();
}
}
}
运行起来之后,可以使用jps命令来查看运行起来的java应用的pid,然后使用下面的命令开始使用工具进行cpu profile数据采集:
./profiler.sh start $pid
一段时间之后,比如30秒后,就可以使用下面的命令来停止数据采集了:
./profiler.sh stop $pid
然后,会打印处下面的信息:
可以很直观的看出,占用cpu时间最多的是method3,占用了93.06%的cpu时间,然后是method2和method1,所以很明显method3就是性能瓶颈,也就是所谓的热点代码,需要着手进行优化。当然,上面是有的命令式是比较简单的,下面来介绍一个比较厉害的命令,可以设定采集数据的时间,并且可以将采集到的数据dump起来,然后使用FlameGraph工具来生成火焰图进行直观的分析。当然,首先需要运行起来代码,并且使用jps找到应用的pid,然后可以使用下面的命令来进行数据采集任务:
./profiler.sh -d 10 -o collapsed -f /home/collapsed.txt pid
这个命令的意思是说,采集数据的时间为10秒,并且将数据按照collapsed规范进行dump,并且dump到/home/collapsed.txt这个文件,过了10秒之后,工具会自动停止,并且将cpu的profile数据dump到指定的路径(按照指定的规范),可以到/home/collapsed.txt查看具体的文件内容,但是很大程度上是看不懂的,所以需要使用FlameGraph工具来进行加工一下,可以使用下面的命令来生成火焰图:
/home/FlameGraph/flamegraph.pl --colors=java /home/collapsed.txt > flamegraph.svg
可以在当前目录下发现多了一个flamegraph.svg文件,使用chorm打开,就可以看到下面的图片内容(可以点击放大的):