How To Generate Flame Graphs in Java – DZone – Uplaza

Flame graphs grew to become the de facto customary for investigating points in at present’s functions (not solely written in Java). The flame graphs can present loads of fascinating insights and may give builders priceless hints to enhance the execution of their functions. Nonetheless, nonetheless, loads of builders do not use them, even when producing flame graphs is less complicated than ever earlier than. 

On this article, I’ll display a few examples of how simple it’s in Java to get began with the investigation of your functions. If you do not know the small print about flame graph visualization, please, go to an awesome article about flame graphs from Brendan Gregg. 

Let’s Get Began With Jeffrey CLI

I will be utilizing the Jeffrey CLI (Command-Line Interface) device for producing a flame graph. It is a fairly new and easy-to-use device to your terminal that accepts JFR (JDK Flight Recorder) recordings and generates flame graphs from occasions saved contained in the binary information.

Jeffrey takes the JFR file and generates the graphs and information included right into a single HTML file, subsequently, you’ve a really handy method to share it along with your colleagues.  

For the sake of completeness, I would like to say that there’s additionally Jeffrey App. It is a web-based resolution with a operating Java backend serving information dynamically and containing another fascinating options over the Jeffrey CLI device. Nonetheless, let’s focus simply on technology flame graphs at present. 

There are some limitations over the server-based resolution Jeffrey App coming from the “static nature” of the generated file. Jeffrey App dynamically generates information on the server behind the scenes. The options beneath aren’t out there within the CLI resolution. Nonetheless, there are some mitigations of those shortcomings:

  • Dynamic looking within the time collection graph is just not offered. We are able to use the CLI parameter to separate the time collection graph on the time of executing the command.
  • Zooming of the time collection graph is just not propagated to the flame graph.

If you happen to by no means heard about JFR recordings, then let’s begin with a quick introduction. JFR stands for JDK Flight Recorder and it is a built-in function for amassing occasions out of your JVM and Java software in OpenJDK builds. It generates optimized binary information with all of the collected occasions + metadata to appropriately parse the occasions from the file. On the time of writing this text, there are two widespread methods to generate this binary file:

The generated binary file from whichever method has completely the identical construction and may be processed by Jeffrey CLI. 

Obtain and Startup

Essentially the most simple manner is to obtain it instantly from GitHub.

I will be utilizing pre-generated recordings from Jeffrey’s Take a look at Software. Take a look at the recordings and replica the jeffrey-cli.jar to the identical folder to make simpler and shorter instructions. The recordings from the GitHub repository above have been generated utilizing AsyncProfile which makes use of its personal CPU (jdk.ExecutionSample) and Allocation (jdk.ObjectAllocationInNewTLAB) occasions and these occasions will probably be utilized in our examples beneath.

jeffrey-cli.jar is simply an executable jar file that executes primary instructions with some arguments to specify the conduct.

Based on HELP command, on the time of penning this weblog submit, we will generate flame graphs, sub-second graphs, and their differential graphs (comparability between the identical occasion varieties from JFR recordings). Let’s focus simply on flame graphs on this article.

$ java -jar jeffrey-cli.jar --help
Utilization:  [-hV] [COMMAND]
Generates a flamegraph in keeping with the chosen event-type
  -h, --help      Present this assist message and exit.
  -V, --version   Print model data and exit.
Instructions:
  flame            Generates a Flamegraph (default: jdk.ExecutionSample)
  flame-diff       Generates a Differential Flamegraph (default: jdk.ExecutionSample)
  occasions           Listing all event-types containing a stacktrace for constructing a flamegraph
  sub-second       Generates Sub-Second graph (the primary 5 minutes)
  sub-second-diff  Generates Differential Sub-Second graph (the primary 5 minutes)

Flame Graph With a Default Occasion Sort

There are a number of arguments to make clear the generated output, let’s give attention to the principle ones. Execute flame --help command to point out the knowledge beneath.

$ java -jar jeffrey-cli.jar flame --help
Utilization:  flame [-htVw] [--with-timeseries] [-e=] [--end-time=] [-o=] [-s=] [--start-time=] 
Generates a Flamegraph (default: jdk.ExecutionSample)
                   one JFR file for fetching occasions
  -e, --event-type=
                             Selects occasions for producing a flamegraph (e.g. jdk.ExecutionSample)
      --end-time=   Relative finish in milliseconds from the start of the JFR file
  -h, --help                 Present this assist message and exit.
  -o, --output=  Path to the file with the generated flamegraph (default is the present folder with a filename '.html')
  -s, --search-pattern=
                             Just for timeseries (timeseries can not dynamically searches within the generated file, solely the flamegraph can)
      --start-time=
                             Relative begin in milliseconds from the start of the JFR file
  -t, --thread               Teams stacktraces omitted on the actual thread
  -V, --version              Print model data and exit.
  -w, --weight               Makes use of occasion's weight as a substitute of # of samples (at the moment supported: jdk.ObjectAllocationSample, jdk.ObjectAllocationInNewTLAB, jdk.
                               ObjectAllocationOutsideTLAB, jdk.ThreadPark, jdk.JavaMonitorWait, jdk.JavaMonitorEnter)
      --with-timeseries      Contains Timeseries graph with a Flamegraph (it is `true` by default, set `false` to have solely the Flamegraph) 

The only command beneath generates the CPU flame graph (based mostly on jdk.ExecutionSample) to the identical folder with the title of the recording (you should utilize the output argument to specify the output’s filename and path).

java -jar jeffrey-cli.jar flame jeffrey-persons-full-direct-serde.jfr
Generated: 

Open in your favourite browser.

Flame Graph for a Particular Occasion Sort

One other instance beneath makes use of a selected event-type with a weight possibility. Since we all know that the recording was generated utilizing async-profiler with an alloc possibility, then we have to use jdk.ObjectAllocationInNewTLAB because the event-type to get the suitable outcome.

The weight possibility is beneficial on this case as a result of we wish to be targeted extra on the trail producing extra bytes as a substitute of extra samples. In any other case, we might be misled by loads of samples with non-significant allotted quantities of reminiscence that may conceal fascinating spots with fewer samples however large allotted chunks.

$ java -jar jeffrey-cli.jar flame --event-type=jdk.ObjectAllocationInNewTLAB --weight jeffrey-persons-full-direct-serde.jfr
Generated: 

Flame Graph Grouped by Threads

In some circumstances, it is helpful to generate a graph the place samples are grouped by a selected thread generated by the given pattern (particularly for wall-clock samples, nonetheless, it is smart for different varieties as effectively).

$ java -jar jeffrey-cli.jar flame --thread jeffrey-persons-full-direct-serde.jfr
Generated: 

Looking in Time Collection and Flame Graph

As talked about earlier than, it isn’t attainable to make use of zooming and looking instantly from the generated graph due to its static nature. Nonetheless, at the least we will generate the graph with a search-pattern possibility to separate the time collection graph into two collection:

  1. Samples that comprise the search-pattern
  2. The remainder of the samples that aren’t matched

We seek for Compile sample within the samples to level out the compilation overhead over the time of the recording.

$ java -jar jeffrey-cli.jar flame --search-pattern=Compile jeffrey-persons-full-direct-serde.jfr
Generated: 

Abstract

Mess around, check out different use circumstances, and let me find out about your findings. Thanks for studying my article and please go away your feedback beneath. When you’ve got any concepts to make Jeffrey a greater device to make use of, or if you wish to file a bug, please, go to Jeffrey’s GitHub Repository. 

The subsequent article might be about differential graphs! Keep tuned!

Share This Article
Leave a comment

Leave a Reply

Your email address will not be published. Required fields are marked *

Exit mobile version