How to collect Java Flight Recorder (JFR) data for troubleshooting application performance

  • Updated

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.

The contents should be recorded to a location that the file can be retrieved from and sent to Contrast Security for analysis.
The agent's logging level should be set to 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.

Steps for agent versions older than 6.28.0 end here. Contents below are for agent versions newer than 6.28.0

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=start

This 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=5m

If 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=1h

The 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=30m

This skips the first 5 minutes, then records for 30 minutes, then stops.

Examples

Minimal — start with all defaults:

-Dcontrast.agent.java.jfr_recording=start

Custom output directory and faster dumps:

-Dcontrast.agent.java.jfr_recording=dir=/var/log/jfr,dump_interval=1m

Limited disk usage:

-Dcontrast.agent.java.jfr_recording=disk_limit=500m

Capture a 30-minute window after warmup:

-Dcontrast.agent.java.jfr_recording=delay_start=10m,record_for=30m,dir=/tmp/jfr-capture

Unlimited disk, larger buffer, detailed settings:

-Dcontrast.agent.java.jfr_recording=disk_limit=0,maxsize=512m,settings=profile,dump_interval=5m

Log 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=true

After 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:

Was this article helpful?

0 out of 0 found this helpful

Have more questions? Submit a request