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 lots of fascinating insights and can provide builders useful hints to enhance the execution of their functions. Nevertheless, nonetheless, lots 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 a fantastic article about flame graphs from Brendan Gregg. 

Let’s Get Began With Jeffrey CLI

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

Jeffrey takes the JFR file and generates the graphs and information included right into a single HTML file, subsequently, you have got a really handy method to share it together 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 instrument. Nevertheless, 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 accessible within the CLI resolution. Nevertheless, there are some mitigations of those shortcomings:

  • Dynamic looking within the time collection graph isn’t offered. We will use the CLI parameter to separate the time collection graph on the time of executing the command.
  • Zooming of the time collection graph isn’t propagated to the flame graph.

When you by no means heard about JFR recordings, then let’s begin with a short introduction. JFR stands for JDK Flight Recorder and it is a built-in characteristic for amassing occasions out of your JVM and Java utility in OpenJDK builds. It generates optimized binary recordsdata with all of the collected occasions + metadata to accurately parse the occasions from the file. On the time of writing this text, there are two frequent 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

Probably the most easy manner is to obtain it instantly from GitHub.

I will be utilizing pre-generated recordings from Jeffrey’s Check Utility. 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 had 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.

In response to HELP command, on the time of scripting 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 accordance 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           Record 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 Kind

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 indicate the data 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't 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 present 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 best command beneath generates the CPU flame graph (primarily based on jdk.ExecutionSample) to the identical folder with the title of the recording (you should use 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 Kind

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

The weight choice is beneficial on this case as a result of we need to be centered extra on the trail producing extra bytes as a substitute of extra samples. In any other case, we might be misled by lots of samples with non-significant allotted quantities of reminiscence that might disguise 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 instances, it is helpful to generate a graph the place samples are grouped by a particular thread generated by the given pattern (particularly for wall-clock samples, nonetheless, it is smart for different varieties as nicely).

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

Looking out in Time Sequence and Flame Graph

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

  1. Samples that include 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 instances, and let me find out about your findings. Thanks for studying my article and please depart your feedback beneath. If in case you have any concepts to make Jeffrey a greater instrument 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