The following article is provided on an advice basis only. This article references third party software that may require licensing.
JFR is a profiling and event collection framework built into the Oracle JDK. It allows Java administrators and developers to gather detailed low-level information about how the Java Virtual Machine (JVM) and the Java application are behaving. JFR has an almost unnoticeable impact on the performance of a Java application running in the JVM (overhead is usually well below 1%).
You may be asked to provide a JFR recording by Push Technology support. This article explains how to make a JFR recording.
It is important that your recording captures the issue happening. A JFR recorded while the server is behaving normally is rarely useful.
Creating a Recording
Two startup flags must be enabled on the JVM for which you want to do flight recording.
-XX:+UnlockCommercialFeatures
-XX:+FlightRecorder
Configuring the Diffusion server to automatically record a JFR on startup
This can be done by editing the startup script diffusion.sh or diffusion.bat and adding the following line:
ENABLE_JFR=" -XX:+UnlockCommercialFeatures -XX:+UnlockDiagnosticVMOptions -XX:+DebugNonSafepoints -XX:+FlightRecorder -XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=../logs -XX:StartFlightRecording=compress=true,maxsize=512m"
For this configuration the only requirement is to replace the value of dumponexitpath with the path you want your JFR files to be saved to. You can set the recording to have a maximum size or age with the following parameters:
maxsize=size
Append the letter k or K to indicate kilobytes, m or M to indicate megabytes, g or G to indicate gigabytes, or do not specify any suffix to set the size in bytes.
maxage=age
Append the letter s to indicate seconds, m to indicate minutes, h to indicate hours, or d to indicate days. You can also configure the recording to be written to a file when the JVM exits by setting the dumponexit parameter to true and specifying a path to save it to, like this:
-XX:FlightRecorderOptions=defaultrecording=true,dumponexit=true,dumponexitpath=../logs
The JFR recordings will be found under the logs folder in your Diffusion installation. The full example given above will configure the Diffusion startup script to record a JFR recording when Diffusion is started and write it to a file in the logs directory designated by dumponexitpath when it exits. In this example, the recording is set to keep the latest 512m which should be sufficient data. When starting Diffusion you will see a confirmation of the recording in the console output:
Started recording 1.
Use JFR.dump recording=1 filename=FILEPATH to copy recording data to file.
Creating a dump of the recording from the command line.
In order to manually create a dump of the current recording, issue these commands in the following order: The jps command is used to get the PID for the Diffusion server, in this case 24054.
$ jps
24054 Diffusion
24265 Jps
Then jcmd JFR.check can be issued to get an overview of all current recordings:
$ jcmd 24054 JFR.check
24054:
Recording: recording=1 name="Recording 1" (running)
‘Recording 1’ is currently running, so you can write a dump of its state with the following command:
$ jcmd 24054 JFR.dump recording=1 filename=~/TestRecording.jfr
24054:
Dumped recording 1, 2.7 MB written to:
~/TestRecording.jfr
You can then open the JFR file that was created in Java Mission Control to analyse the dump that was taken.
Using the Command Line to start a manual recording.
In order to start a manual recording, you need the PID for the Diffusion process, which you can obtain as in the previous example. In this case, the PID is 12093:
$ jps
12093 Diffusion
12141 Jps
To begin a 60 second recording, issue the following command using the PID obtained above:
$ jcmd 12093 JFR.start duration=60s sfilename=testrecording.jfr
Starting the recording from the command line has its advantages as it can be scripted or run on servers where GUI access is impractical.
Using the Java Mission Control GUI tool to start a manual recording.
Start Java Mission Control by entering the following command into the command line:
$ jmc
Click the ‘Start Using’ button at the bottom of the window. Run the application that you would like to profile. The application will show in the list in the left panel. Right click on the program and select ‘Start Flight Recording’. In the dialog, choose the name, length, and location of the recording and press Next.
In the next screen you can configure the settings and then press Finish. This saves the recording to the specified location. We recommend that you take thread dumps every 60s.
Saving a JFR recording prior to exit
Diffusion out-of-the-box is configured to use dumponexit=true which will save a JFR when the JVM exits deliberately or otherwise. This can be useful when diagnosing unplanned outages, however it is known to truncate the coverage of the resulting JFR. To save all collected JFR data before a planned outage use JFR.dump and JFR.stop to save and cease JFR data recording.
Sending to Support
Once your recording has been created, please compress the JFR file and send to Push Technology Support. If the file is too large to be emailed, please contact our support team, who will make alternative arrangements.
Recommended optimisation
We propose that the following change is made to the profile configuration (typically found at $JAVA_HOME/jre/lib/jfr/profile.jfc) due to a performance issue in the JVM:
<event path="java/socket_read">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
<setting name="threshold" control="http://www.oracle.com/hotspot/jvm/socket-io-threshold">10 ms</setting>
</event>
<event path="java/socket_write">
<setting name="enabled">false</setting>
<setting name="stackTrace">true</setting>
<setting name="threshold" control="http://www.oracle.com/hotspot/jvm/socket-io-threshold">10 ms</setting>
</event>
You can find more details about this issue which has now been resolved at this page of the JDK bug system.