Java Flight Recorder (JFR) is a tool for helping debug many kinds of performance issues. JFR captures a large set of JVM performance information into a flight recording file. The recording can then be analyzed offline using Java Mission Control.
As of Contrast Java Agent version 6.28.0, the agent can generate JFR captures. If you are using a version newer than 6.28.0 this will be the easiest way to proceed.
Expand here if using Java agent versions older than 6.28.0 and unable to upgrade
Note: JFR is not available on IBM JREs. Please see - How to generate a YourKit session if using an IBM JRE.
OpenJDK 8u262 and 11+
JFR is available in OpenJDK 11+. Additionally, it was back-ported to OpenJDK 8u262, so all recent OpenJDK 1.8 distributions should have JFR available.
We normally ask that you capture a profiling recording via modifying
the
settings property to
settings=profile.
This recording will be automatically dumped on the JVM stopping with
the
addition of dumponexit=true.
WARN
or
ERROR when capturing the profiling recording.
See
agent.logger configuration at -
Java Configuration
for further details.
What settings=profile captures may vary from
Java release
to release. The following are a few example configurations
for starting a JFR:
# Record to file "recording.jfr", use the settings "profile"
-XX:StartFlightRecording=filename=recording.jfr,dumponexit=true,settings=profile
# Record to file "recording.jfr", record for 5mins before dumping results, use the settings "profile"
-XX:StartFlightRecording=filename=recording.jfr,duration=300s,dumponexit=true,settings=profile
# Record to file "recording.jfr", delay starting recording for 30s, use the settings "profile"
-XX:StartFlightRecording=filename=recording.jfr,delay=30s,dumponexit=true,settings=profile
Recording to disk manually using jcmd
The following example recording to disk and using jcmd requires a JDK install and access to the server/container running the application. For example:
-XX:StartFlightRecording=disk=true,name=recording-1,filename=/tmp/agent.jfr,maxage=15m,dumponexit=true,settings=profile
Then, log in to the application server and run jcmd
to find
the process ID.
Then, run jcmd <PID> JFR.dump filename=/recording.jfr
to record the data.
Requirements
Java agent version 6.28.0 or newer.
A version of the JVM that supports JFR. Therefore excluded are:
Early versions of Java 8
IBM OpenJ9 JVMs
On unsupported JVMs this config is a noop.
Quick Start
The simplest way to enable automatic JFR recording is to set the contrast.agent.java.jfr_recording property to start:
-Dcontrast.agent.java.jfr_recording=startThis starts recording immediately with all defaults applied. No other configuration is required.
Without setting anything, automatic recording is disabled by default as per before.
The default is to record forever, so if you need the recordings to stop then ensure you set record_for to a reasonable value.
How It Works
When enabled, the agent starts a JFR recording and periodically dumps incremental .jfr files to disk. Each dump file contains only the events from its recording interval — files do not overlap. On JVM shutdown, a final dump is written automatically.
Dump files are named: <name>-<6-digit-id>-<yyyyMMdd-HHmmss-SSS>.jfr
For example: contrast-agent-482917-20260304-143022-847.jfr
The 6-digit ID is randomly generated per agent session to prevent filename collisions when multiple agents write to the same directory.
Configuration
The property accepts a comma-separated list of key=value pairs. All keys are optional — any omitted key uses its default.
-Dcontrast.agent.java.jfr_recording=dir=/var/log/contrast,dump_interval=5m,disk_limit=1g
| Key | Description | Default |
| name | Recording name visible in JDK Mission Control (JMC) and used as the filename prefix | contrast-agent |
| settings | JFR configuration name (default, profile ) or path to a .jfc file |
profile |
| dir | Directory to write dump files into | java.io.tmpdir |
| dump_inteval |
How often to dump the recording to disk (minimum: 30s ) |
10m |
| maxsize | Max in-memory JFR buffer size | 256m |
| maxage | Max age of events retained in the in-memory buffer | not set |
| disk_limit | Total disk budget for dump files in the output directory (0 = unlimited) | 2g |
| delay_start | not set (starts immediately), example delay_start=5m
|
not set (starts immediately) |
| gzip | Whether to gzip the dumped files or not. Gzipping (the default) saves space but takes more CPU. Options are true or false | true |
Duration values
Durations support the suffixes ms, s, m, h. A bare number is treated as seconds.
Examples: 500ms, 30s, 10m, 2h, 60
Size values
Sizes support the suffixes k/kb, m/mb, g/gb (case-insensitive). A bare number is treated as bytes.
Examples: 512k, 256m, 256mb, 2g, 2gb, 1073741824
Size Limits
There are two independent size controls:
maxsize — In-memory buffer limit (default: 256 MB)
This controls how much event data JFR keeps in its circular in-memory buffer. When the buffer fills up, the oldest events are evicted. This directly affects the maximum size of each individual dump file. Increasing this value retains more event history per dump but uses more heap memory.
disk_limit — Total disk budget (default: 2 GB)
This controls the total size of all contrast-*.jfr files in the output directory. After each dump, the agent checks whether the total size of agent-created JFR files exceeds the limit. If it does, the oldest files are deleted until the total is back within budget. Files not created by the agent (those not matching the contrast-*.jfr pattern) are ignored.
Given the size limit is enforced after writing the current file, there is a chance the total size will for a period be over the limit set in disk_limit and customers should provide a buffer in terms of size.
Setting disk_limit=0 disables disk limit enforcement entirely (unlimited).
How they interact: maxsize controls how large each individual dump can be. disk_limit controls how many dumps are retained on disk. For example, with maxsize=256m and disk_limit=2g, the agent retains roughly 8 dump files before the oldest ones are cleaned up.
Delayed Start and Fixed-Duration Recording
delay_start
Delays the start of the recording by the specified duration. This is useful when you want to skip the application startup phase and only capture steady-state behaviour.
-Dcontrast.agent.java.jfr_recording=delay_start=5mIf the JVM shuts down before the delay elapses, no recording is produced and a warning is logged.
record_for
Records for a fixed duration, then performs a final dump and stops. No further recordings are taken, and the shutdown hook does not produce an additional dump.
-Dcontrast.agent.java.jfr_recording=record_for=1hThe timer starts from when the recording actually begins (after any delay_start), not from agent startup.
Combining both
-Dcontrast.agent.java.jfr_recording=delay_start=5m,record_for=30mThis skips the first 5 minutes, then records for 30 minutes, then stops.
Examples
Minimal — start with all defaults:
-Dcontrast.agent.java.jfr_recording=startCustom output directory and faster dumps:
-Dcontrast.agent.java.jfr_recording=dir=/var/log/jfr,dump_interval=1mLimited disk usage:
-Dcontrast.agent.java.jfr_recording=disk_limit=500mCapture a 30-minute window after warmup:
-Dcontrast.agent.java.jfr_recording=delay_start=10m,record_for=30m,dir=/tmp/jfr-captureUnlimited disk, larger buffer, detailed settings:
-Dcontrast.agent.java.jfr_recording=disk_limit=0,maxsize=512m,settings=profile,dump_interval=5mLog Messages
A log message will be logged on startup when the config is detected
2026-03-06 10:42:07,517 [main JfrRecordingManagerImpl] INFO - JFR auto-capture enabled: id=872490, name=contrast-agent, settings=profile, dir=/Users/jmccartney/tmp/2026/2026-q1/misc/jfr, dump_interval=PT1M, disk_limit=157286400 bytes, maxsize=268435456 bytes, maxage=null, gzip=trueAfter each file is written a message will be recorded
2026-03-06 11:36:07,647 [Contrast IO Executor JfrRecordingManagerImpl] INFO - JFR recording dumped to /Users/contrast/tmp/2026/2026-q1/misc/jfr/contrast-agent-872490-20260306-113607-540.jfr
See also: