Build and Run Native Executables with JFR

JDK Flight Recorder (JFR) is a tool for collecting diagnostic and profiling data about a running Java application, built into the JVM. GraalVM Native Image supports JFR events and users can use the jdk.jfr.Event API with a similar experience to using JFR in the Java HotSpot VM.

To collect JFR events when running a native executable, enable JFR support and JFR event recording as described in this guide.

Note: JFR event recording is not yet supported on GraalVM JDK for Windows.

Enable JFR Support and Record Events at Run Time

To build a native executable with JFR events support, add the --enable-monitoring=jfr option when invoking the native-image tool, and then start JFR recording at runtime.

Follow the steps below to practice building a native executable with JFR support and recording events at run time.

Prerequisite

Make sure you have installed a GraalVM JDK. The easiest way to get started is with SDKMAN!. For other installation options, visit the Downloads section.

  1. Save the following code to the file named JFRDemo.java.
     import jdk.jfr.Event;
     import jdk.jfr.Description;
     import jdk.jfr.Label;
    
     public class JFRDemo {
    
       @Label("Hello World")
       @Description("Build and run a native executable with JFR.")
       static class HelloWorldEvent extends Event {
           @Label("Message")
           String message;
       }
    
       public static void main(String... args) {
           HelloWorldEvent event = new HelloWorldEvent();
           event.message = "Hello, World!";
           event.commit();
       }
     }
    

    This demo application consists of a simple class and JDK library classes. It creates an event, annotated with @Label from the jdk.jfr.* package. If you run this application, it will not print anything and just run that event.

  2. Compile the Java file using the GraalVM JDK:
     javac JFRDemo.java
    

    It creates two class files: JFRDemo$HelloWorldEvent.class and JFRDemo.class.

  3. Build a native executable with VM inspection enabled:
     native-image --enable-monitoring=jfr JFRDemo
    

    The --enable-monitoring=jfr option enables features such as JFR that can be used to inspect the VM.

  4. Run the executable and start recording:
     ./jfrdemo -XX:StartFlightRecording="filename=recording.jfr"
    

    This command runs the application as a native executable. The -XX:StartFlightRecording option enables the built-in Flight Recorder and starts recording to a specified binary file, recording.jfr.

  5. Start VisualVM to view the contents of the recording file in a user-friendly way.

  6. Go to File, then Add JFR Snapshot, browse recording.jfr, and open the selected file. Confirm the display name and click OK. Once opened, there are several options you can check (such as Monitoring, Threads, and Exceptions) but you are mostly interested in browsing events. It will look something like this:

    JDK Flight Recorder

    Alternatively, you can view the contents of the recording file in the console window by running this command:

     jfr print recording.jfr
    

    It prints all the events recorded by Flight Recorder.