Skip to content
AITroveRead. Build. Understand.
Make this comfortable

Java Flight Recorder: a bounded recording and a checked artifact

Last updated: 5 Oct 20264 min read
tutorial
IntermediateBy AITrove Editorial

Java Flight Recorder collects enabled runtime and application events into a recording that can be inspected after the observed workload.

Java 11+. This is a complete program using JDK classes.

Ask a workload question first

A parcel importer can be slow because it allocates heavily, waits on a lock or blocks on storage. A recording helps distinguish those causes when the relevant events are enabled. A single elapsed-time number cannot tell which resource caused the delay.

This program records one application event carrying a parcel count. It explicitly enables the event type, commits the event, stops the recording and reads the dumped artifact. That checks the recording pipeline without claiming it profiles an actual production import.

Keep identifying data out of event fields unless the diagnostic policy allows it. Recording files can outlive the process and move between machines. Bound recording retention and decide who can inspect the artifact before enabling it for requests containing private business data.

Separate heap evidence from timing evidence

Allocation events can help find allocation pressure. A heap dump answers retained-object questions and can be much larger. A retained heap graph, a thread dump and a recording describe different observations; choose the artifact that can answer the question rather than collecting every possible file.

Working program

Java
import jdk.jfr.Event;
import jdk.jfr.Label;
import jdk.jfr.Recording;
import jdk.jfr.consumer.RecordingFile;
import java.nio.file.*;
public class ParcelFlightRecording {
    @Label("Parcel batch")
    static class BatchEvent extends Event { int parcels; }
    public static void main(String[] args) throws Exception {
        Path artifact = Files.createTempFile("aitrove-batch-", ".jfr");
        try {
            try (Recording recording = new Recording()) {
                recording.enable(BatchEvent.class).withoutThreshold();
                recording.start();
                BatchEvent event = new BatchEvent(); event.parcels = 42; event.commit();
                recording.stop(); recording.dump(artifact);
            }
            boolean found = RecordingFile.readAllEvents(artifact).stream()
                .anyMatch(event -> event.getEventType().getName().equals(BatchEvent.class.getName()) && event.getInt("parcels") == 42);
            System.out.println("Batch event found=" + found);
        } finally { Files.deleteIfExists(artifact); }
    }
}

Output

Output
Batch event found=true

Costs and boundaries

Recording overhead depends on enabled events, thresholds and workload. No overhead percentage is measured here. readAllEvents loads this tiny fixture entirely; large recordings should be inspected with a streaming reader and an explicit storage budget. A JFR-capable JDK is required.

Common Mistakes

  • Do not publish an overhead claim without measuring the target workload.
  • A recording is not a heap dump.
  • A program that records one event is not a production load test.

Read next

Heap and collector observations, Object retention.

Continue with: Java ThreadMXBean CPU time: check support and the disabled state, Java MemoryMXBean: read used, committed, and an optional maximum.

java
flight-recorder
Storage details