skip to content

How do you start a JFR recording — both at JVM launch and on an already-running process — and how do you produce a .jfr file from it?

level: middleimportance: must knowfreq 60%

answer

  1. Launch flag: -XX:StartFlightRecording=duration,filename,settings
  2. Live process: jcmd <pid> JFR.start / .check / .dump / .stop
  3. dump = snapshot while running; stop = end recording
  4. settings=default (cheap) vs profile (richer)
  5. Programmatic: jdk.jfr.Recording

basics

~20 s

At launch, add the JVM flag -XX:StartFlightRecording with options like duration and filename. On a running process, use the jcmd tool: 'jcmd <pid> JFR.start', then 'JFR.dump' to write a .jfr file and 'JFR.stop' to end it.

solid answer

~40 s

There are two main ways to drive JFR. At JVM startup you pass -XX:StartFlightRecording=... with comma-separated options, e.g. -XX:StartFlightRecording=duration=60s,filename=app.jfr,settings=profile. For a process already running, you use the jcmd command-line tool against its PID: jcmd <pid> JFR.start name=rec settings=profile to begin, jcmd <pid> JFR.dump name=rec filename=app.jfr to write the buffered data to a file, jcmd <pid> JFR.check to list active recordings, and jcmd <pid> JFR.stop name=rec to end it. The settings parameter selects a configuration template — typically 'default' (very low overhead, safe for continuous production use) or 'profile' (richer events, slightly higher cost, for focused investigation). You can also dump on exit (dumponexit=true) or automatically on OutOfMemoryError. The output .jfr file is then opened in JDK Mission Control.

code

java · 21 lines
java
// Start at launch (shell):
//   java -XX:StartFlightRecording=duration=60s,filename=app.jfr,settings=profile -jar app.jar
//
// Control a running process by PID (shell):
//   jcmd <pid> JFR.start name=rec settings=default maxage=10m maxsize=100m
//   jcmd <pid> JFR.check
//   jcmd <pid> JFR.dump  name=rec filename=incident.jfr
//   jcmd <pid> JFR.stop  name=rec

// Or programmatically, inside the application, via the jdk.jfr API:
import jdk.jfr.Recording;
import java.nio.file.Path;
import java.time.Duration;

var recording = new Recording();
recording.setDuration(Duration.ofSeconds(60));
recording.setName("rec");
recording.start();
// ... let the app run ...
recording.dump(Path.of("app.jfr")); // write buffered events to a file
recording.stop();

go deeper

for a junior

Knows the two ways to start: the -XX:StartFlightRecording launch flag and jcmd on a live process, and that the result is a .jfr file.

for a middle

Can list the common options (duration, filename, settings, name, maxage/maxsize), distinguish dump vs stop, and pick default vs profile appropriately.

for a senior

Designs an always-on continuous recording with a bounded ring buffer (maxage/maxsize) plus incident-triggered JFR.dump, and knows the programmatic jdk.jfr API and dumponexit / dump-on-OOM triggers.

for a principal

Standardizes JFR enablement across the fleet (custom .jfc templates, FlightRecorderOptions tuning, repository placement), automates dump collection, and balances event coverage against overhead budgets.

## The two entry points JFR is controlled either **at JVM launch** (a flag) or **on a live JVM** (the `jcmd` tool). Both produce the same thing: a binary **`.jfr`** recording file. ### 1. At launch — `-XX:StartFlightRecording` You add a single JVM flag with comma-separated `key=value` options: ``` java -XX:StartFlightRecording=duration=60s,filename=app.jfr,settings=profile -jar app.jar ``` Common options: - **`duration`** — how long to record (omit it for an *unbounded/continuous* recording). - **`filename`** — where to write the `.jfr` (if omitted, you must dump it later). - **`settings`** — the configuration template name (`default` or `profile`, or a custom `.jfc` file). - **`name`** — a label so you can refer to this recording later via `jcmd`. - **`maxsize` / `maxage`** — cap the buffered data by size or by time window (for continuous recordings). - **`dumponexit=true`** — write the file automatically when the JVM shuts down. ### 2. On a running process — `jcmd` `jcmd` is a JDK diagnostic command tool. You target a process by its **PID** (process id; `jcmd` with no arguments or `jps` lists Java PIDs). The JFR sub-commands: ``` jcmd <pid> JFR.start name=rec settings=profile jcmd <pid> JFR.check # list active recordings jcmd <pid> JFR.dump name=rec filename=app.jfr # snapshot current buffer to a file jcmd <pid> JFR.stop name=rec filename=app.jfr # stop AND write the file ``` Key distinction: **`JFR.dump`** writes out what is buffered *so far* while the recording keeps going; **`JFR.stop`** ends the recording (and can also write the file). This is the basis of the 'always-on, dump-on-incident' pattern: start an unbounded recording with a `maxage`/`maxsize` ring buffer, and when something goes wrong, `JFR.dump` the recent window. ### Settings templates: default vs profile The **`settings`** parameter chooses how much to record: - **`default`** — conservative, **< 1% overhead**, intended to be safe for continuous production recording. - **`profile`** — denser sampling and more event types, **slightly higher overhead**, for a focused profiling session. - A **custom `.jfc`** file (you can author one in JMC) lets you turn individual event types and their thresholds on or off. ### Other triggers - **`-XX:FlightRecorderOptions`** tunes global buffer sizes and repository location. - You can also start/stop recordings **programmatically** via the `jdk.jfr` API (`Recording` class) inside the application. ### Where the file goes next The `.jfr` is a self-contained binary file of typed events; you open it in **JDK Mission Control (JMC)** (or parse it with the `jdk.jfr.consumer` API / `jfr print` CLI) to analyze.

  • What is the difference between JFR.dump and JFR.stop?
    JFR.dump writes the currently buffered events to a file while the recording continues running; JFR.stop ends the recording entirely (and can also write the file). dump is what you use for the 'always-on, snapshot on incident' pattern.
  • When would you choose the 'default' settings template over 'profile'?
    Use 'default' for continuous, always-on recording in production because it keeps overhead under ~1%. Use 'profile' for a time-boxed investigation where you want denser method sampling and more event types and can tolerate slightly higher cost.

saying these in an interview costs you the question

  • Thinking you need a third-party tool to start a recording — it is a JVM flag or jcmd, both shipped with the JDK.
  • Confusing JFR.dump (snapshot, keeps recording) with JFR.stop (ends recording).
  • Believing you must restart the JVM with a flag to profile — jcmd attaches to an already-running process.
  • Saying 'profile' settings are always best — they cost more; 'default' is the production-safe template.

context