Published in


JDK Flight Recorder Support in VisualVM

A preview version of the JDK Flight Recorder support has been released as a plugin for the VisualVM tool bundled with GraalVM 19.2. The plugin reads all JFR snapshots created from Java 7 and newer and presents the data in typical VisualVM views familiar to the tool users.

JDK Flight Recorder (JFR, previously Java Flight Recorder) is a tool for collecting diagnostic and profiling data about a running Java application. It is integrated into the Java Virtual Machine (JVM) and causes almost no performance overhead, so it can be used even in heavily loaded production environments.

Monitor tab of the VisualVM JFR viewer

These views and functionality are currently available:

  • Overview tab displays the basic information about the recorded process like its main class, arguments, JVM version and configuration, and system properties. This tab also provides access to the recorded thread dumps.
  • Monitor tab shows the process’ uptime and basic telemetry — CPU usage, Heap & Metaspace utilization, number of loaded classes and number of live & started threads.
  • Threads tab reconstructs the threads timeline based on all events recorded in the snapshot as precisely as possible, based on the recording configuration.
  • Locks tab allows to analyze threads synchronization.
  • File IO tab presents information on read and write events to the filesystem.
  • Socket IO tab presents information on read and write events to the network.
  • Sampler tab shows per-thread CPU utilization and memory allocations, and a heap histogram. There’s also an experimental feature “CPU sampler” building CPU snapshot from the recorded events. It does not provide an exact performance analysis but still helps to understand what was going on in the recorded application and where the CPU bottleneck might be.
  • Browser tab provides a generic browser of all events recorded in the snapshot.
  • Environment tab gives an overview of the recording machine setup and condition like CPU model, memory size, operating system version, CPU utilization, memory usage, etc.
  • Recording tab lists the recording settings and basic snapshot telemetry like number of events, total recording time, etc.

Some advanced features like analyzing JVM internals, showing event stack traces or support for creating JFR snapshots from live processes are not available in the preview version and will be addressed incrementally in the following releases.

Threads tab of the VisualVM JFR viewer

To install the JFR support, download GraalVM 19.2 or newer from, install it and run <GRAALVM_HOME>/bin/jvisualvm to start VisualVM. Use Tools | Plugins | Available Plugins to list all available plugins and install the VisualVM-JFR and VisualVM-JFR-Generic modules. The JFR snapshots can be opened using either the File | Load... action or by doubleclicking the JFR Snapshots node and adding the snapshot into the JFR repository permanently.

Please follow the documentation for your Java version to create JFR snapshots. For GraalVM Enterprise the JFR snapshot can be created by adding the following parameters to the java command:

<GRAALVM_HOME>/bin/java -XX:+UnlockCommercialFeatures 
-XX:StartFlightRecording=duration=10s,filename=filename.jfr -jar ...

Note that creating JFR snapshots in GraalVM 19.2 CE is not available as the underlying OpenJDK 8 doesn’t support it. You can use OpenJDK 11 and newer to create JFR snapshots:

<OPENJDK11_HOME>/bin/java -XX:StartFlightRecording=duration=10s,filename=filename.jfr -jar ...
Environment tab of the VisualVM JFR viewer

Trying it out

If you want to test it on a Java application but don’t have your favorite readily available you can try, for example, the Spring Petclinic sample web application. Clone, build, and prepare it:

git clone
mvn clean package -DskipTests=true
# verify it works:
<GRAALVM_HOME>/bin/java -jar target/spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar

This would start the sample application and make it available on localhost:8080.

Now you just need to add the command line options above to the java command and the Flight Recorder will gather the profiling information.

<GRAALVM_HOME>/bin/java -XX:+UnlockCommercialFeatures -XX:StartFlightRecording=dumponexit=true,filename=petclinic.jfr -jar target/spring-petclinic-2.1.0.BUILD-SNAPSHOT.jar

Note the dumponexit=true commands to fill the file at the end of the application run, another option would be to specify the duration of the recording.

Open the application and click around, or if you have a load generating tool, for example, wrk, you can use it to generate the sample workload for more meaningful profile. For example, the following command would apply load for 30 seconds to one of the webpages in the running app.

wrk -d30s -R2000 http://localhost:8080/owners\?lastName\=

Stop the application, verify the petclinic.jfr file exists, and load it into VisualVM as described above.

You can now investigate what date JFR recorded about your application from VisualVM:

JFR data for a sample run of Spring Petclinic application displayed in VisualVM

Note, JFR recordings are one of the best tools for performance analysis, if you have a workload which you’d like GraalVM Enterprise to handle better, you can contact the GraalVM team, for example, on GitHub and we’ll try to investigate if there are opportunities for optimizations.

We’ll appreciate your feedback on the JFR support in VisualVM — please let us know which features would you like to see in the next version! Leave your comments below this article or at, or file a RFE/bug at



Get the Medium app

A button that says 'Download on the App Store', and if clicked it will lead you to the iOS App store
A button that says 'Get it on, Google Play', and if clicked it will lead you to the Google Play store