Java Flight Recorder (JFR) is a tool for collecting diagnostic and profiling data about a running Java application. It is integrated into the Java Virtual Machine (JVM) and causes almost no performance overhead, so it can be used even in heavily loaded production environments. When default settings are used, both internal testing and customer feedback indicate that performance impact is less than one percent. For some applications, it can be significantly lower. However, for short-running applications (which are not the kind of applications running in production environments), relative startup and warmup times can be larger, which might impact the performance by more than one percent. JFR collects data about the JVM as well as the Java application running on it.
Compared to other similar tools, JFR has the following benefits:
Provides better data: A coherent data model used by JFR makes it easier to cross reference and filter events.
Allows for third-party event providers: A set of APIs allow JFR to monitor third-party applications, including WebLogic Server and other Oracle products.
Reduces total cost of ownership: JFR enables you to spend less time diagnosing and troubleshooting problems, reduces operating costs and business interrupts, provides faster resolution time when problems occur, and improves system efficiency.
JFR is primarily used for:
Profiling
JFR continuously saves large amounts of data about the running system. This profiling information includes thread samples (which show where the program spends its time), lock profiles, and garbage collection details.
Black Box Analysis
JFR continuously saves information to a circular buffer. This information can be accessed when an anomaly is detected to find the cause.
Support and Debugging
Data collected by JFR can be essential when contacting Oracle support to help diagnose issues with your Java application.
Java Flight Recorder collects data about events. Events occur in the JVM or the Java application at a specific point in time. Each event has a name, a time stamp, and an optional payload. The payload is the data associated with an event, for example, the CPU usage, the Java heap size before and after the event, the thread ID of the lock holder, and so on.
Most events also have information about the thread in which the event occurred, the stack trace at the time of the event, and the duration of the event. Using the information available in events, you can reconstruct the runtime details for the JVM and the Java application.
JFR collects information about three types of events:
A duration event takes some time to occur, and is logged when it completes. You can set a threshold for duration events, so that only events lasting longer than the specified period of time are recorded. This is not possible for other types of events.
An instant event occurs instantly, and is logged right away.
A sample event (also called requestable event) is logged at a regular interval to provide a sample of system activity. You can configure how often sampling occurs.
JFR monitors the running system at an extremely high level of detail. This produces an enormous amount of data. To keep the overhead as low as possible, limit the type of recorded events to those you actually need. In most cases, very short duration events are of no interest, so limit the recording to events with a duration exceeding a certain meaningful threshold.
JFR collects data from the JVM (through internal APIs) and from the Java application (through the JFR APIs). This data is stored in small thread-local buffers that are flushed to a global in-memory buffer. Data in the global in-memory buffer is then written to disk. Disk write operations are expensive, so you should try to minimize them by carefully selecting the event data you enable for recording. The format of the binary recording files is very compact and efficient for applications to read and write.
There is no information overlap between the various buffers. A particular chunk of data is available either in memory or on disk, but never in both places. This has the following implications:
Data not yet flushed to a disk buffer will not be available in the event of a power failure.
A JVM crash can result in some data being available in the core file (that is, the in-memory buffer) and some in the disk buffer. JFR does not provide the capability to merge such buffers.
There may be a small delay before data collected by JFR is available to you (for example, when it has to be moved to a different buffer before it can be made visible).
The data in the recording file may not be in time sequential order as the data is collected in chunks from several thread buffers.
In some cases, the JVM drops the event order to ensure that it does not crash. Any data that cannot be written fast enough to disk is discarded. When this happens, the recording file will include information on which time period was affected. This information will also be logged to the logging facility of the JVM.
You can configure JFR to not write any data to disk. In this mode, the global buffer acts as a circular buffer and the oldest data is dropped when the buffer is full. This very low-overhead operating mode still collects all the vital data necessary for root-cause problem analysis. Because the most recent data is always available in the global buffer, it can be written to disk on demand whenever operations or surveillance systems detect a problem. However, in this mode, only the last few minutes of data is available, so it only contains the most recent events. If you need to get the full history of operation for a long period of time, use the default mode when events are written to disk regularly.
JFR is comprised of the following components:
JFR runtime is the recording engine inside the JVM that produces the recordings. The runtime engine itself is comprised of the following components:
The agent controls buffers, disk I/O, MBeans, and so on. This component provides a dynamic library written in C and Java code, and also provides a JVM-independent pure Java implementation.
The producers insert data into the buffers. They can collect events from the JVM and the Java application, and (through a Java API) from third-party applications.
Flight Recorder plugin for Java Mission Control (JMC) enables you to work with JFR from the JMC client, using a graphical user interface (GUI) to start, stop, and configure recordings, as well as view recording files.
By default, JFR is disabled in the JVM. To enable JFR, you must launch your Java application with the -XX:+FlightRecorder
option. Because JFR is a commercial feature, available only in the commercial packages based on Java Platform, Standard Edition (Oracle Java SE Advanced and Oracle Java SE Suite), you also have to enable commercial features using the -XX:+UnlockCommercialFeatures
options.
For example, to enable JFR when launching a Java application named MyApp
, use the following command:
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder MyApp
For more information about these and other options, see the java
command reference page under JDK Tools and Utilities.