How to get Java profiling dump for creating flame graphs on Mac?

I would like to collect stacktraces from my Java application to create graphics processor plugins for profiling.

This is very similar to this question: How to get a full stack dump from the profiler in each example for use in a flame graph? with 2 differences:

  • I work with Java code and I need a Java stack stack
  • I am working on a Mac (this means that there is no pref and AFAIK dtrace on OSX does not support the jstack extension).

I have already tried lightweight-java-profiler and Honest profiler , and both of them seem to not work on Mac. I also tried VisualVM , but I could not get it to create stacktrace dumps that I needed.

The first prioirty for me is flame graphs created from the Java stack, but having my own set of calls would also be great because it allowed me to address I / O issues (and possibly even generate hot / cold flame graphs ).

+6
source share
4 answers

I created 2 small shell scripts based on @cello's answer. They generate hot / cold flame graphics .

Get them from this gist .

Using:

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

Alternatively, to measure the application from starting (in this case, in my gradle assembly, which also needed to be run in a different directory and with some input stream), I used:

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

Results:

flame graphs

In this example, I can clearly see that my application is connected with I / O (note the blue bars at the top).

+4
source

Try the following: https://github.com/saquibkhan/javaFlameGraph

Installation

npm install javaflamegraph

Using

  • cd javaflamegraph
  • npm start - This will wait until it detects a process named "Java". It is best to use the start of profiling in the launch program.
  • npm run start <process id> - This will start profiling for the given process id. e.g. npm run start 1234
+3
source

Have you tried the jstack command? just run it on the command line: jstack pidOfJavaProcess > stack.txt (naturally, replacing pidOfJavaProcess with the actual process number). You can run this in a loop in bash (the default shell used on Mac OS X):

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

pay attention to >> to add to the file, and not to overwrite it every second. Press Ctrl+C to stop recording stack traces.

This will only generate Java stack traces, and not native call stacks from the JVM.

+2
source

The good news: there is a β€œscript” for working with jstacks in the FlameGraph repository.

https://github.com/brendangregg/FlameGraph

This is stackcollapse-jstack.pl .

It seems that by default it only expects a stack trace after a stack trace at its input and considers each of them to be a "fetch point".

That way, you can just do a few jstack in a file (run this one or more times, or once per second "for a while", etc.):

jstack pid_of_your_jvm >> my_jstack

Then run this script:

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

and finally convert to flameograph:

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

No third-party helpers are required (although they can still be useful).

Also note that non-RUNNABLE threads are discarded in the stackcollapse-jstack.pl file, you can configure it if you also want to enable β€œunoccupied” threads (this is usually not the case).

Apparently you can use the linux "perf" command to generate stacks for the Java process, and also see README https://github.com/brendangregg/FlameGraph

This may include more of your own calls, for example.

+1
source

Source: https://habr.com/ru/post/1208032/


All Articles