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

mik*_*1aj 7 java profiling visualization stack-trace

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

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

  1. 我使用Java代码,我需要Java堆栈跟踪
  2. 我在Mac上工作(这意味着没有pref,dtraceOSX上的AFAIK 不支持jstack扩展).

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

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

mik*_*1aj 6

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

从这个要点中获取它们。

用法:

ps ax | grep java # find the PID of your process
./profile.sh 20402 stacks.txt
./gen.sh stacks.txt
Run Code Online (Sandbox Code Playgroud)

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

cd ../my-project; ./gradlew --no-daemon clean build < /dev/zero &; cd -; ./profile.sh $! stacks.txt
./gen.sh stacks.txt
Run Code Online (Sandbox Code Playgroud)

结果:

火焰图

在此示例中,我可以清楚地看到我的应用程序受 I/O 限制(注意顶部的蓝色条)。


rog*_*ack 6

好消息,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
Run Code Online (Sandbox Code Playgroud)

最后转换为火焰图:

 ./flamegraph.pl --color=java my_jstack.folded > my_jstack.svg
Run Code Online (Sandbox Code Playgroud)

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

另请注意,该stackcollapse-jstack.pl文件会丢弃非 RUNNABLE 线程,如果您还想包括“空闲”线程(通常您不这样做),您可能需要调整它。

Apparently you could use the linux "perf" command to generate stacks for a java process, as well, see the README https://github.com/brendangregg/FlameGraph

This might include more native calls, for instance.