JVM tool guide · jvm cli

Java Flight Recorder (JFR): Always-On JVM Profiling

Java Flight Recorder (JFR) is the JVM's built-in, extremely low-overhead event recorder. It captures profiling events — CPU sampling, allocations, garbage collection, locks, exceptions, JIT compilation — continuously, with overhead typically measured in the low single-digit percentage. That makes it eligible to run in production permanently, which is why it is the backbone of modern Java observability.

JFR data is stored in a ring buffer inside the JVM and can be started at launch with -XX:StartFlightRecording, or on demand with jcmd JFR.start. Recordings (.jfr files) are analyzed in JDK Mission Control, or parsed with the standalone jfr command.

Official java -XX:StartFlightRecording / jfr project

Use it when

• You want always-on profiling without paying a big overhead penalty.

• You need to reconstruct 'what was the JVM doing' after an incident — JFR's ring-buffer history is the closest thing to a JVM black box.

• You need CPU, allocation, GC, lock and exception data from one consistent source.

Skip it when

• You need stack-level sampling at extremely high frequency beyond JFR defaults — async-profiler samples more aggressively.

• You need source-level method timing with line numbers — fine here but richer in a dedicated profiler.

Start JFR at launch

Start a rolling recording when the JVM boots. Settings from the default.jfc are a good baseline; use profile.jfc for more detail at higher overhead.

java -XX:StartFlightRecording=filename=/logs/app.jfr,dumponexit=true,disk=true,settings=profile -jar app.jar

Start / dump / stop with jcmd

Manage the recording from outside the process. You can start a bounded recording, then dump its contents without stopping it.

jcmd <pid> JFR.start name=prod duration=5m filename=/tmp/prod.jfr
jcmd <pid> JFR.check
jcmd <pid> JFR.dump name=prod filename=/tmp/prod.jfr
jcmd <pid> JFR.stop name=prod

Read a recording with the jfr command

The standalone jfr tool prints summary or per-event information without opening a GUI.

# Summary / metadata
jfr summary /tmp/prod.jfr

# Print recorded events (counts, breakdowns)
jfr print --events jdk.GCPhasePause /tmp/prod.jfr

Analyze in JDK Mission Control

JMC is the primary analysis UI for JFR: open the .jfr file, browse flame graphs, allocation and lock analysis, and GC pause views.

jmc
Quick start

Get productive in minutes

Record on demand and inspect

One pass: start a short bounded recording, wait, then read back its summary.

jcmd <pid> JFR.start duration=30s filename=diag.jfr
# ...let it run 30 seconds...
jfr summary diag.jfr

Frequently asked questions

Does JFR affect production performance?

With the default event settings, overhead is typically under 1-2%. The profile setting is more expensive; pick it carefully. The disk-based ring buffer lets you dump history after an incident.

JFR vs async-profiler — do I need both?

They complement each other. JFR gives broad, always-on events and incident-replay (especially GC, locks, exceptions). async-profiler gives deeper, lower-level CPU and native-stack sampling on demand. Many teams run JFR continuously and async-profiler during focused investigations.

Which JDK versions include JFR?

JFR became open and freely usable in OpenJDK 11 and is included in all current Oracle JDK and OpenJDK distributions. If you must target an older JDK 8 build, JFR features vary by vendor.

Last updated August 2026 · JVM Tools is independent and not affiliated with Oracle.