如何获取Java分析转储以在mac上创建火焰图?

时间:2014-12-01 13:00:18

标签: java profiling visualization stack-trace

我想从我的Java应用程序中收集堆栈跟踪,以便为分析创建CPU Flame Graphs

这与此问题非常相似:How to get complete stack dump from profiler in every sample for use in flame graph?有2个不同之处:

  1. 我使用Java代码,我需要Java stacktraces
  2. 我在Mac上工作(这意味着OSX上没有pref和AFAIK dtrace并且不支持jstack扩展名。)
  3. 我已经尝试了lightweight-java-profilerHonest profiler,而且他们似乎都不适用于Mac。我也试过VisualVM,但是我无法生成我需要的堆栈跟踪转储。

    对我来说,第一个prioirty是从Java堆栈跟踪生成的火焰图,但是拥有本机调用堆栈也会很棒,因为它可以让我解决I / O问题(甚至可能生成hot/cold flame graphs)。

4 个答案:

答案 0 :(得分:4)

我根据@ cello的答案创建了2个小shell脚本。他们生成hot/cold flame graphs

this Gist获取他们。

用法:

ps ax | grep java # find the PID of your process
./profile.sh 20402 stacks.txt
./gen.sh stacks.txt

或者,要从启动测量应用程序(在这种情况下,我的gradle构建也需要在另一个目录中运行并使用一些输入流)我使用了:

cd ../my-project; ./gradlew --no-daemon clean build < /dev/zero &; cd -; ./profile.sh $! stacks.txt
./gen.sh stacks.txt

结果:

flame graphs

在这个例子中,我可以清楚地看到我的应用程序是I / O绑定的(注意顶部的蓝色条)。

答案 1 :(得分:3)

试试这个:https://github.com/saquibkhan/javaFlameGraph

  

安装

     

npm install javaflamegraph

     

用法

     
      
  1. cd javaflamegraph
  2.   
  3. npm start - 这将等到它检测到名为&#39; Java&#39;的进程。可以最好地用于在程序中开始分析   启动。
  4.   
  5. npm run start <process id> - 这将开始分析给定的进程ID。   例如npm run start 1234
  6.   

答案 2 :(得分:2)

您是否尝试过jstack命令?只需在命令行上运行它:jstack pidOfJavaProcess > stack.txt(当然,用实际进程号替换pidOfJavaProcess)。您可以在bash中循环运行(Mac OS X上使用的默认shell):

while true; do jstack pidOfJavaProcess >> stack.txt; sleep 1.0; done

请注意要附加到文件的>>,而不是每秒覆盖一次。按Ctrl+C以停止记录堆栈跟踪。

这只会生成java堆栈跟踪,而不是JVM中的本机调用堆栈。

答案 3 :(得分:1)

好消息,FlameGraph存储库中有一个“脚本”可用于其中已存在的jstacks。

https://github.com/brendangregg/FlameGraph

这是stackcollapse-jstack.pl

似乎默认情况下,它期望在输入中仅跟踪堆栈跟踪,然后将每个堆栈跟踪都算作“样本点”。

因此,您可以将多个jstack放入一个文件中(运行一次或几次,或者每秒“一段时间”等):

jstack pid_of_your_jvm >> my_jstack

然后执行该脚本:

 ./stackcollapse-jstack.pl my_jstack > my_jstack.folded

最后转换为火焰图:

 ./flamegraph.pl --color=java my_jstack.folded > my_jstack.svg

不需要第三方帮助程序(尽管它们可能仍然有用)。

还请注意,stackcollapse-jstack.pl文件会丢弃非RUNNABLE线程,如果您还想包含“空闲”线程(通常不包含),则可能要进行调整。

显然,您也可以使用linux“ perf”命令为Java进程生成堆栈,请参见自述文件https://github.com/brendangregg/FlameGraph

例如,这可能包括更多的本地调用。