concept

JFR (Java Flight Recorder) data is a historical event of the JVM that is used to diagnose the JVM’s historical performance and operations. Is a monitoring tool that collects information about JVM events during Java application execution. JFR opens a set of events, and when an event occurs, the corresponding data is kept in a file or in memory (if a cache pool is enabled). JMC can display these events — retrieved in real time from the JVM or from a file. JMC can display detailed JFR-recorded data. JFR The performance overhead for the monitored application is low by default: less than 1% of the application’s performance, but increases as more events or logging threads are started.

JFR has two main concepts: events and data flows

The event

JFR collects events that occur while a Java application is running. There are three main types of events available for JFR collection:

  • Instant event: Data is recorded immediately once an event occurs
  • Duration event: If the duration exceeds the specified threshold, the data is recorded
  • Simple events: Used to record active indicators (such as CPU, memory, etc.) of the system where the application is running

The data flow

Events collected by JFR contain a lot of data, which is stored in filenfilename. JFR, and disk I/O operations are notoriously expensive. Therefore, JFR uses various caches to store the collected data before flushing the data blocks to disk. In some cases, JFR data can be lost because of caching. If a loss of data occurs, JFR attempts to notify the output file that part of the information is missing.

preparation

I have Java Mission Control 8 installed locally (the latest version at the time this article was published). JMC can be used in conjunction with JFR, and JMC can visually display the XXX.jFR files generated by JFR. The data presentation is very rich. This will be explained in detail later in the article.

use

Enable with configuration parameters:

#Add the following two parameters to enable the corresponding JFR function
java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder
Copy the code

The parameters configured in Tomcat do not take effect. If you have solved the problem, you can leave the comment section

Enable it using the command line

Use the JCMD command line to unlock the JFR function.

JCMD process_id VM. Unlock_commercial_features Unlocks the privileges of the JFR recording functionCopy the code

Use JCMD command line to start a recording thread, duration record time period, default is 0s, indicates unlimited, the following code uses 200s, indicates the end of record 200s. Filename Indicates the name of the file to save.

JCMD JCMD process_id jfr. start duration=100s filename=flight.jfrCopy the code

Command line details

The JCMD command contains all the operations that operate JFR, and now the operations and parameters are explained in detail. First, if you don’t know the rules of the command line, you can use the JCMD help command to understand the explanation of the command line. For example, to view a jfr. check command line and specify the corresponding process ID (5361 in this article), use the following command line:

jcmd 5361 help JFR.check

#Command line return value
5361:
JFR.check
Checks running JFR recording(s)

Impact: Low

Permission: java.lang.management.ManagementPermission(monitor)

Syntax : JFR.check [options]

Options: (options must be specified using the <key> or <key>=<value> syntax)
	name : [optional] Recording name, e.g. \"My Recording\" or omit to see all recordings (STRING, no default value)
	recording : [optional] Recording number, or omit to see all recordings (JLONG, -1)
	verbose : [optional] Print event settings for the recording(s) (BOOLEAN, false)
Copy the code

Based on the English meanings, you can learn how to use each parameter, corresponding meanings, and precautions. To get to the point, there are four types of JCMD commands associated with JFR:

  • Jfr. start — Start a new JFR logging thread
  • Jfr. check — Checks running JFR logging threads
  • Jfr. stop — Stops a specified JFR logging thread
  • Jfr. dump – copies the contents of a specified JFR logging thread into a file

Each command line has corresponding parameters. This section describes the corresponding parameters in detail

JFR.start

parameter instructions Value types The default value
name Record the name of the thread String There is no
settings Server side template String There is no
defaultrecording Start default recording Boolean False
delay The delay in starting recording Time 0s
duration Duration of recording Time 0S (for ever, without interruption)
filename Name of record String
compress The result file of the record is compressed using GZip Boolean False
maxage Maximum lifetime of buffer data Time 0S indicates that there is no time limit
maxsize The maximum number of cache capacity Long 0 means there is no maximum size

JFR.check

parameter instructions Value types The default value
name Record the name of the thread String There is no
recording Log the ID value of the thread Long 1
verbose Whether to print detailed data information Boolean False

JFR.stop

parameter instructions Value types The default value
name Record the name of the thread String There is no
recording Log the ID value of the thread Long 1
discard Discarding recorded data Boolean There is no
copy_to_file Copy recorded data to a file String There is no
compress_copy GZip compresses the “copy_to_file” file Boolean False

JFR.dump

parameter instructions Value types The default value
name Record the name of the thread String There is no
recording Log the ID value of the thread Long 1
copy_to_file Copy recorded data to a file String There is no
compress_copy GZip compresses the “copy_to_file” file Boolean False

In actual combat

After introducing the command line usage and parameter description, it is time to use JFR in action. A note of caution here is that although JFR is designed to have a small impact on JVM and application performance, it is best to set duration, maximum lifetime of buffer data (maxage), and limit the maximum amount of data collected (maxsize). First define a memory leak main program, the specific code is as follows:

public static void main(String[] args) {
    List<Object> items = new ArrayList<>(1);
    try {
        while (true){
            items.add(newObject()); }}catch (OutOfMemoryError e){
        System.out.println(e.getMessage());
    }
    assert items.size() > 0;
    try {
        Thread.sleep(1000);
    } catch(InterruptedException e) { System.out.println(e.getMessage()); }}Copy the code

Use the startup command:

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder 
  -XX:StartFlightRecording=duration=200s,filename=flight.jfr 
Copy the code

After the project is started and an OutOfMemoryError has occurred, you will find a file named flight.jfr in the directory. Drag the file into JDK Mission Control and it will be analyzed automatically. The following figure shows the result of JDK Mission Control analysis:Now let’s analyze the results of this graph in detail:

  • The red score on the right of the picture indicates that the key parts of this analysis will be described in detail after expansion, such as the first pointApplication HaltsIndicates that the application pauses are too long due to GC. If you really do not want to see, copy paste paste into the translation software, you will understand the general meaning.
  • The sidebar on the left side of the image shows a detailed record of each analysis block, with memory, GC, I/O, and so on, and the little red exclamation mark is the most important part to look at. For example, let’s look at memory

As you can see from the figure, the application memory usage runs out quickly within 5 seconds and then triggers a GC operation. What causes the memory usage to run so fast? According to theMethod ProfilingAs can be seen from the analysis result of ArrayList copy operation, as shown in the figure below:

By the above operation we can quickly locate the memory overflow method block, the use of other blocks we can analyze the time to view, are very convenient visual interface. When using JFR, do not define too large time blocks, or need to be divided into small time blocks for analysis, because large time blocks will lead to huge JFR files, local analysis, will also produce lag or computer memory is not enough, resulting in the local machine stuck, unable to analyze.

The resources

Monitoring Java Applications with Flight Recorder Java Performance Authority Guide JDK Mission Control