29.1 Java Flight Recorder
Capture low-overhead performance and diagnostic data for production applications using built-in JFR events.
Starting a Recording
java -XX:StartFlightRecording=settings=profile,filename=recording.jfr,duration=60s MyApp
Settings:
default: Low overhead (~1%).profile: More detail (~2% overhead).
Recording at Runtime (JFR API)
import jdk.jfr.Recording;
import jdk.jfr.Configuration;
import java.nio.file.Path;
Configuration config = Configuration.getConfiguration("profile");
try (Recording rec = new Recording(config)) {
rec.start();
// application logic
Thread.sleep(10_000);
rec.dump(Path.of("runtime.jfr"));
}
Key Event Types
- jdk.Compilation: JIT compilation activity.
- jdk.GarbageCollection: GC pause times.
- jdk.ObjectAllocationSample: Allocation hotspots.
- jdk.JavaMonitorEnter: Lock contention.
- jdk.ThreadPark: Thread parking events.
- jdk.FileRead/FileWrite: I/O operations.
Analyzing with JDK Mission Control (JMC)
jmc recording.jfr
Visualize timelines, identify bottlenecks (GC, locks, allocations), and drill into hot methods.
Custom Events
import jdk.jfr.*;
@Name("com.example.MyEvent")
@Label("My Custom Event")
class MyEvent extends Event {
@Label("Operation Name") String operation;
@Label("Duration") long durationMs;
}
MyEvent evt = new MyEvent();
evt.begin();
// business logic
evt.end();
evt.operation = "processOrder";
evt.durationMs = evt.getDuration().toMillis();
if (evt.shouldCommit()) evt.commit();
Production Use
- Run with
settings=defaultfor continuous monitoring. - Store recordings externally for post-mortem analysis.
- Use JFR with monitoring tools (Prometheus, Grafana via JMX).
Guidance
- Start with
profilesettings for troubleshooting; usedefaultin production. - Combine JFR with GC logs and JMX metrics for comprehensive observability.
- Analyze allocation profiles to identify memory churn.
- Use custom events to track business-critical operations.