我想从我的Java应用程序中收集堆栈跟踪,以创建用于分析的CPU Flame Graphs。
这与这个问题非常相似:How to get complete stack dump from profiler in every sample for use in flame graph?有2个不同之处:
pref
和AFAIK dtrace
不支持jstack
extension)。我已经尝试过lightweight-java-profiler和Honest profiler,而且它们似乎都不适用于Mac。我也试过VisualVM,但我无法让它产生我需要的堆栈跟踪转储。
对我来说第一个prioirty是从Java堆栈跟踪生成的火焰图,但是拥有本机调用堆栈也会很棒,因为它可以让我解决I / O问题(甚至可能生成hot/cold flame graphs)。
我根据@ 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
结果:
在这个例子中,我可以清楚地看到我的应用程序是I / O绑定(注意顶部的蓝色条)。
试试这个:https://github.com/saquibkhan/javaFlameGraph
安装
npm install javaflamegraph
用法
cd javaflamegraph
npm start
- 这将等到它检测到名为“Java”的进程。可以最好地用于在程序启动时开始分析。npm run start <process id>
- 这将开始分析给定的进程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
例如,这可能包括更多本机调用。