Skip to main content

JDK Flight Recorder

JDK Flight Recorder (JFR) can work with Native Image.

With the current version of GraalVM, the support of JFR is quite limited. Most VM-internal events and advanced features are still missing. Only custom and system events and disk-based recordings are supported.

Basic Usage

To add JFR support, the native image needs to be built with the -H:+AllowVMInspection option.

native-image -H:+AllowVMInspection Main

When JFR is included, it can be enabled using the -XX:+FlightRecorder option. A recording is started by adding the -XX:StartFlightRecording option. -XX:StartFlightRecording specifies the configurations to start a JFR recording. The value is a comma-separated list of key-value pairs.

KeyDefault valueDescription
nameName of the recording
settingsJFR settings file
delayDelay to start recording
duration0 (infinite)Duration of recording in seconds
filenameName of the recording file
maxage0 (no limit)Maximum time to keep the recording
maxsize0 (no limit)Maximum amount of bytes of the recording
dumponexitfalseWhether to dump the recording on exit
Start JFR recording
./app -XX:+FlightRecorder \
-XX:StartFlightRecording="filename=recording.jfr,dumponexit=true,duration=1m"

The recording file can be opened by VisualVM or JDK Mission Control.

The figure below shows a JFR recording in JDK Mission Control. It only has a limited set of events.

JFR recording in JDK Mission Control

Custom Events

An important JFR feature than can be used in the current GraalVM version is custom events. ServiceAccessEvent in the code below is a custom JFR event. This class represents an event that a service is accessed.

Custom JFR event
import jdk.jfr.Description;
import jdk.jfr.Event;
import jdk.jfr.Label;

@Label("Service access")
@Description("Access a service")
class ServiceAccessEvent extends Event {
@Label("Service name")
String name;
}

The code below shows a JAX-RS resource. In the recordServiceAccess method, a new ServiceAccessEvent is created and committed. When the API endpoint /hello is accessed, a new event will be committed.

Simple REST service
import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("/hello")
public class GreetingResource {

@GET
@Produces(MediaType.TEXT_PLAIN)
public String hello() {
recordServiceAccess("hello");
return "Hello World!";
}

private void recordServiceAccess(String name) {
ServiceAccessEvent event = new ServiceAccessEvent();
event.name = name;
event.commit();
}
}

In the JFR recording, this custom event will be displayed.

JFR custom events