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.
Key | Default value | Description |
---|---|---|
name | Name of the recording | |
settings | JFR settings file | |
delay | Delay to start recording | |
duration | 0 (infinite) | Duration of recording in seconds |
filename | Name of the recording file | |
maxage | 0 (no limit) | Maximum time to keep the recording |
maxsize | 0 (no limit) | Maximum amount of bytes of the recording |
dumponexit | false | Whether to dump the recording on exit |
./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.
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.
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.
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.