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

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

这与此问题非常相似: 如何在每个样本中从分析器获取完整的堆栈转储以用于火焰图? 有2个不同之处:

  1. 我使用Java代码,我需要Java堆栈跟踪
  2. 我正在使用Mac(这意味着OSX上没有pref和AFAIK dtrace不支持jstack扩展)。

我已经尝试过轻量级java-profiler和Honest profiler ,但它们似乎都不适用于Mac。 我也试过VisualVM ,但我无法让它产生我需要的堆栈跟踪转储。

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

我根据@ cello的答案创建了2个小shell脚本。 它们生成热/冷火焰图 。

从这个要点中获取它们。

用法:

 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 

结果:

火焰图

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

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

安装

npm install javaflamegraph

用法

  1. cd javaflamegraph
  2. npm start – 这将等到它检测到名为’Java’的进程。 可以最好地用于在程序启动时开始分析。
  3. npm run start – 这将开始分析给定的进程ID。 例如, npm run start 1234

你试过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的本机调用堆栈。

好消息是,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进程生成堆栈,参见README https://github.com/brendangregg/FlameGraph

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