101. Java Flight Recorder (JFR) & Low-Overhead Production Profiling
Java Flight Recorder (JFR) is an always-on, low-overhead (<1% CPU) event tracing and profiling framework integrated into the JVM kernel, paired with JDK Mission Control (JMC) for diagnostics.
Java 21+ (Built into OpenJDK)Explanation
Traditional profilers often attach via JVM TI agents or sampling threads that inject significant overhead (10โ30%), distorting benchmark results and making continuous production profiling risky. Java Flight Recorder (JFR) is integrated directly into the HotSpot runtime engine. It writes binary event buffers with under 1% overhead, making it safe to run 24/7 in high-throughput production environments.
JFR captures fine-grained events: CPU sampling, memory allocation rates, garbage collection pauses, thread locks/contention, I/O latency (file and socket), class loading, and virtual thread pinning events (jdk.VirtualThreadPinned). Events are recorded into rotating in-memory circular buffers or dumped to .jfr files on trigger conditions.
Developers can also define custom application events by subclassing jdk.jfr.Event. These custom business events (e.g., checkout latency, DB query duration) are correlated with underlying JVM metrics (GC spikes, lock contention) inside analysis tools like JDK Mission Control (JMC) or exported to Prometheus/Grafana.
Example
import jdk.jfr.Category;
import jdk.jfr.Description;
import jdk.jfr.Event;
import jdk.jfr.Label;
import jdk.jfr.Name;
public class JfrCustomEventDemo {
// Define a custom production JFR event
@Name("com.example.OrderProcessing")
@Label("Order Processing Event")
@Category({"Business", "Orders"})
@Description("Measures time spent validating and processing customer orders")
static class OrderEvent extends Event {
@Label("Order ID")
private String orderId;
@Label("Total Amount")
private double amount;
public void setOrderId(String id) { this.orderId = id; }
public void setAmount(double amt) { this.amount = amt; }
}
public static void processOrder(String id, double amount) {
OrderEvent event = new OrderEvent();
event.setOrderId(id);
event.setAmount(amount);
event.begin(); // Mark start time
try {
// Simulated business logic
Thread.sleep(15);
} catch (InterruptedException ignored) {
} finally {
event.commit(); // Writes event if enabled by active JFR profile
}
}
public static void main(String[] args) {
System.out.println("Processing sample orders with JFR event emission...");
processOrder("ORD-1001", 149.99);
System.out.println("Done. Run with: -XX:StartFlightRecording=filename=app.jfr,dumponexit=true");
}
}Sources
- https://docs.oracle.com/en/java/javase/21/jfapi/flight-recorder.html โ Java Flight Recorder Guide
- https://dev.java/learn/jvm/jfr/ โ dev.java JFR Overview