JFR View Command in Java 21 – Java 21 中的 JFR 视图命令

最后修改: 2024年 1月 24日

中文/混合/英文(键盘快捷键:t)

1. Introduction

1.导言

Java Flight Recorder (JFR) is a profiling and diagnostic tool that monitors the JVM and the programs that run on it. It’s a handy profiling tool developers use to monitor the state and performance of their applications.

Java Flight Recorder (JFR) 是一款剖析和诊断工具,用于监控JVM和在其上运行的程序。它是一款方便的剖析工具,开发人员可利用它来监控应用程序的状态和性能。

This tutorial will focus on the new view command introduced in Java 21 for JFR.

本教程将重点介绍 Java 21 中为 JFR 引入的新 view 命令。

2. Java Flight Recorder (JFR)

2.Java 飞行记录仪(JFR)

The Java Flight Recorder (JFR) is a low-overhead application profiling framework introduced in Java 7 as an experimental feature. It allowed us to analyze and understand important metrics about our programs, such as garbage collection patterns, IO operations, memory allocations, and more.

Java Flight Recorder (JFR) 是 Java 7 中引入的低开销应用程序剖析框架,是一项实验性功能。它使我们能够分析和了解程序的重要指标,例如 垃圾收集模式、IO 操作、内存分配等。

2.1. What Is the Java Flight Recorder?

2.1.什么是 Java 飞行记录器?

JFR collects information about the events in the JVM when a Java application runs and we analyze the results with diagnostic tools.

当 Java 应用程序运行时,JFR 会收集 JVM 中事件的相关信息,我们会使用诊断工具对结果进行分析。

JFR monitors the application and records the analysis in a recording file. There are two ways for us to instruct the JFR to monitor an application:

JFR 监控应用程序并将分析结果记录在记录文件中。我们有两种方法指示 JFR 监视应用程序:

  1. Use the command line to start the application and enable JFR.
  2. Use a diagnostic tool such as jcmd on an already running Java application.

The recording is typically generated as a .jfr file, which can then be analyzed by visual tools such as the Java Mission Control (JMC) tool or using the new view command as we’ll see in the upcoming sections.

记录通常以 .jfr 文件的形式生成,然后可通过可视化工具(如 Java Mission Control (JMC) 工具)或使用新的 view 命令对其进行分析,我们将在接下来的章节中看到这一点。

2.2. Recording From the Command Line

2.2.从命令行录音

To demonstrate a flight recording, let’s write a small program that inserts an object into an ArrayList until an OutOfMemoryError is thrown:

为了演示飞行记录,让我们编写一个小程序,将一个对象插入到 ArrayList 中,直到抛出 OutOfMemoryError 为止:

void insertToList(List<Object> list) {
    try {
        while (true) {
            list.add(new Object());
        }
    } catch (OutOfMemoryError e) {
        System.out.println("Out of Memory. Exiting");
    }
}

Let’s compile the program using the standard javac compiler:

让我们使用标准 javac 编译器编译程序:

javac -d out -sourcepath JFRExample.java

Once the .class file is generated, we start the flight recorder. We pass some additional arguments to the java command, namely the -XX:+FlightRecorder option, along with some additional parameters to set the recording duration and the output file path where the recording will be stored:

生成 .class 文件后,我们将启动飞行记录器。我们会向 java 命令传递一些额外的参数,即 -XX:+FlightRecorder 选项,以及一些用于设置记录持续时间和存储记录的输出文件路径的额外参数:

java -XX:StartFlightRecording=duration=200s,filename=flight.jfr -cp ./out/ com.baeldung.jfrview.JFRExample

Our program now runs with JFR enabled to capture the events and other system properties, and JFR writes the results into the flight.jfr file.

现在,我们的程序在启用 JFR 的情况下运行,以捕获事件和其他系统属性,JFR 会将结果写入 flight.jfr 文件。

2.3. Recording Using the jcmd Tool

2.3.使用 jcmd 工具进行记录

The jcmd diagnostic tool provides an alternative way to record and analyze the performance of our applications and JVM. We can register diagnostic events to a running virtual machine using this tool.

jcmd诊断工具提供了另一种记录和分析应用程序和 JVM 性能的方法。我们可以使用该工具向运行中的虚拟机注册诊断事件。

To use the jcmd tool, we need our application to be running and we must know the pid:

要使用 jcmd 工具,我们需要运行应用程序,并且必须知道 pid

jcmd <pid|MainClass> <command> [parameters]

Several commands that the jcmd tool recognizes are:

jcmd工具可以识别的命令有

  • JFR.start – starts a new JFR recording
  • JFR.check – checks running JFR recording(s)
  • JFR.stop – stops a specific JFR recording
  • JFR.dump – copies contents of a JFR recording to file

Each of these commands requires additional parameters.

每条命令都需要附加参数。

Let’s create a recording using the jcmd tool now. We need to start the application and find the pid of the running process. Once we have the pid, we start the recording:

现在让我们使用 jcmd 工具创建一个记录。我们需要启动应用程序并找到运行进程的 pid。获得 pid 后,我们就可以开始录制:

jcmd 128263 JFR.start filename=recording.jfr

We can stop the recording when we’ve captured the relevant events:

我们可以在捕捉到相关事件后停止录制:

jcmd 128263 JFR.stop filename=recording.jfr

3. Viewing the JFR Recording File

3.查看 JFR 记录文件

To view and understand the results of the jfr file, we can use the Java Mission Control (JMC) tool. The JMC tool comes with numerous functionalities to profile and monitor Java applications, including a diagnostic tool that reads JFR files and shows a visual representation of the result:

要查看和了解 jfr 文件的结果,我们可以使用 Java Mission Control (JMC) 工具。JMC 工具具有许多功能,可用于剖析和监控 Java 应用程序,包括一个诊断工具,可读取 JFR 文件并显示结果的可视化表示

Java Mission Control Summary shows a dashboard with the results of the flight recording

4. The jfr Command

4.jfr 命令

The jfr command parses and prints flight recording files (.jfr) to standard output. While we previously used the Mission Control tool for visual representation, the jfr command provides us with a way to filter, summarize, and generate human-readable output from flight recording files in the console.

jfr命令将飞行记录文件(.jfr)解析并打印到标准输出。虽然我们以前使用任务控制工具进行可视化显示,但 jfr 命令为我们提供了一种方法,可以在控制台中对飞行记录文件进行过滤、汇总并生成人类可读的输出。

4.1. Using the jfr Command

4.1.使用 jfr 命令

The jfr command resides in the bin path of the $JAVA_HOME. Let’s look at its syntax:

jfr 命令位于 $JAVA_HOMEbin 路径中。让我们来看看它的语法:

$JAVA_HOME/bin/jfr [command] <path>

In the following sections, we’ll be accessing jfr directly.

在接下来的章节中,我们将直接访问 jfr

4.2. jfr Commands

4.2.jfr 命令

jfr previously had five commands namely print, summary, metadata, assemble, and disassemble. The view command is the sixth jfr command that has been introduced.

jfr 以前有五个命令,即 print, summary, metadata, assemble, disassembleview命令是引入的第六个jfr命令

The print command is used to print the contents of the flight recording and it takes several parameters including the output format(json/xml etc), a range of filters which might include categories, events, and the stack depth:

print 命令用于打印飞行记录的内容,它需要多个参数,包括输出格式(json/xml 等)、一系列筛选器(可能包括类别、事件和堆栈深度):

jfr print [--xml|--json] [--categories <filters>] [--events <filters>] [--stack-depth <depth>] <file>

The summary command as the name suggests generates a summary of the recording that includes the events that occurred, disk space utility etc:

顾名思义,summary 命令生成的记录摘要包括发生的事件、磁盘空间实用程序等:

jfr summary <file>

The metadata command generates detailed information about the events such as their names and categories:

metadata 命令会生成事件的详细信息,如名称和类别:

jfr metadata <file>

Finally, the assemble and disassemble commands are for assembling chunk files into a recording file and vice-versa:

最后,assembledisassemble 命令用于将分块文件装配到录音文件中,反之亦然:

jfr assemble <repository> <file>
jfr disassemble [--max-chunks <chunks>] [--output <directory>] <file>

4.3. Example of a jfr Command

4.3.jfr 命令示例

Now we’ll look at an example jfr command and generate the summary of our JFR file:

现在我们来看一个 jfr 命令的示例,并生成 JFR 文件的摘要:

$JAVA_HOME/bin/jfr summary recording.jfr

 Version: 2.1
 Chunks: 1
 Start: 2023-12-25 17:07:08 (UTC)
 Duration: 1 s

 Event Type                              Count  Size (bytes)
=============================================================
 jdk.NativeLibrary                         512         44522
 jdk.SystemProcess                         511         49553
 jdk.ModuleExport                          506          4921
 jdk.BooleanFlag                           495         15060
 jdk.ActiveSetting                         359         10376
 jdk.GCPhaseParallel                       162          4033

5. The view Command in JDK 21

5.JDK 21 中的 view 命令

Java 21 introduced the view command to facilitate the analysis of JFR recordings from the command line. This new view command eliminates the use of dumping recording downloads into the JMC tool and comes with more than 70 prebuilt options. These options, which are likely to increase over time, cover almost all important aspects of the application including the JVM, the application itself, and the environment of the application.

Java 21 引入了 view 命令,以方便从命令行分析 JFR 录音。这一新的 view 命令无需将记录下载转储到 JMC 工具中,并提供了 70 多个预置选项。这些选项几乎涵盖了应用程序的所有重要方面,包括 JVM、应用程序本身和应用程序的环境,而且随着时间的推移,这些选项可能还会增加。

5.1. Categories of View Options

5.1.视图选项类别

We can broadly classify the different view options into three categories which are similar to the ones displayed in the JMC tool:

我们可以将不同的视图选项大致分为三类,它们与 JMC 工具中显示的选项类似:

  1. Java Virtual Machine Views
  2. Environment Views
  3. Application Views

5.2. JVM Views

5.2 JVM 视图

Java Virtual Machine views give insights into the JVM attributes such as heap space, garbage collection, native memory, and other compiler-related metrics. Some common JVM views include:

Java 虚拟机视图可让人深入了解堆空间、垃圾回收、本地内存等 JVM 属性以及其他与编译器相关的指标。一些常见的 JVM 视图包括

  • class-modifications
  • gc-concurrent-phases
  • compiler-configuration
  • gc-configuration
  • native-memory-committed
  • gc-cpu-time
  • compiler-statistics
  • gc-pause-phases
  • heap-configuration

5.3. Environment Views

5.3.环境视图

Environment views show information about the host system where the JVM is running such as CPU information, network utilization, system properties, process, and information. Some common Environment views are:

环境视图显示运行 JVM 的主机系统的信息,如 CPU 信息、网络利用率、系统属性、进程和信息。一些常见的环境视图包括

  • cpu-information
  • cpu-load
  • jvm-flags
  • container-configuration
  • network-utilization
  • system-processes
  • system-properties

5.4. Application Views

5.4.应用程序视图

Application views provide insights into our application code such as information regarding its thread usage, object statistics, and memory utilization. Some common Application views include:

应用程序视图可帮助我们深入了解应用程序代码,如线程使用情况、对象统计信息和内存使用情况。一些常见的应用程序视图包括

  • exception-count
  • object-statistics
  • allocation-by-thread
  • memory-leaks-by-class
  • thread-cpu-load
  • thread-count
  • thread-allocation

5.5. Command Structure of view

5.5.view 的命令结构

The view command expects a view name and the path to the recording file along with relevant parameters. It can be activated using the jfr command and the jcmd command:

view命令需要一个视图名称和记录文件的路径以及相关参数。可以使用 jfr 命令和 jcmd 命令激活它:

jfr view [view] <recording file>
jcmd <pid> JFR.view [view name]

The output is then displayed on the command line, or any standard output. Additionally, the commands provide customization capabilities on the output format, time ranges, and custom views.

此外,这些命令还提供输出格式、时间范围和自定义视图的自定义功能

6. JFR view Command Usage

6.JFR view 命令用法

In this section, we’ll use the view command with some of the views mentioned in the previous section to analyze the JFR recording file we generated earlier.

在本节中,我们将使用 view 命令和上一节中提到的一些视图来分析之前生成的 JFR 记录文件。

6.1. Using the jfr Command

6.1.使用 jfr 命令

Let’s apply the gc-configuration JVM view on our flight recording using the jfr command and capture the output:

让我们使用 jfr 命令在飞行记录上应用 gc-configuration JVM 视图并捕获输出:

jfr view gc-configuration flight.jfr
GC Configuration
----------------
Young GC: G1New
Old GC: G1Old
Parallel GC Threads: 4
Concurrent GC Threads: 1
Dynamic GC Threads: true
Concurrent Explicit GC: false
Disable Explicit GC: false
Pause Target: N/A
GC Time Ratio: 12

The view, as its name suggests generates information about the GC type being used and other relevant data on garbage collection.

顾名思义,该视图会生成有关正在使用的 GC 类型的信息,以及有关垃圾回收的其他相关数据。

6.2. Using the jcmd Tool

6.2.使用 jcmd 工具

We can use the view command with the jcmd tool as well:

我们还可以通过 jcmd 工具使用 view 命令:

jcmd <pid> JFR.view [view name]

The jcmd tool requires a running pid to diagnose and we’ll request the Environment view system-processes:

jcmd 工具需要运行的 pid 才能进行诊断,我们将请求环境视图 system-processes

jcmd 37417 JFR.view cell-height=3 truncate=beginning width=80 system-processes
                                                    System Processes
First Observed Last Observed PID  Command Line
-------------- ------------- ---- -------------------------------------------------------------------------------------
23:21:26       23:21:26      453  /Applications/Flycut.app/Contents/MacOS/Flycut
23:21:26       23:21:26      780  /Applications/Grammarly Desktop.app/Contents/Library/LaunchAgents/Grammarly Deskto...
23:21:26       23:21:26      455  /Applications/Grammarly Desktop.app/Contents/MacOS/Grammarly Desktop
23:21:26       23:21:26      431  /Applications/JetBrains Toolbox.app/Contents/MacOS/jetbrains-toolbox
23:21:26       23:21:26      624  /Applications/Safari.app/Contents/MacOS/Safari

6.3. Formatting the view Command Output

6.3.设置 view 命令输出的格式

We can play with the output of the view command and adjust it according to our needs. The view command currently provides several options to format the output, including modifying the number of columns and rows, and other options such as a verbose flag and output truncation:

我们可以使用 view 命令的输出,并根据需要对其进行调整。view命令目前提供了多个选项来格式化输出,包括修改列数和行数,以及其他选项,如verbose 标志和输出截断:

--width [number-of-columns]
--cell-height [number of rows]
--verbose [the query that makes up the view]
--truncate [--beginning|--end] [truncate content from beginning or end]

As an example, let’s format the output of the system processes view that we generated above in such a way that each row has two lines and also make the response verbose:

举个例子,让我们把上面生成的系统进程视图的输出格式化,使每一行都有两行,并使响应变得冗长:

jfr view --cell-height 2 --width 100 --truncate beginning --verbose system-processes flight.jfr

                                          System Processes

First Observed Last Observed PID   Command Line
(startTime)    (startTime)   (pid) (commandLine)
-------------- ------------- ----- ----------------------------------------------------------------
23:33:47       23:33:47      453   /Applications/Flycut.app/Contents/MacOS/Flycut
23:33:47       23:33:47      780   ...ions/Grammarly Desktop.app/Contents/Library/LaunchAgents/Gram
                                   marly Desktop Helper.app/Contents/MacOS/Grammarly Desktop Helper
23:33:47       23:33:47      455   /Applications/Grammarly Desktop.app/Contents/MacOS/Grammarly Des
                                   ktop
23:33:47       23:33:47      431   /Applications/JetBrains Toolbox.app/Contents/MacOS/jetbrains-too
                                   lbox
23:33:47       23:33:47      624   /Applications/Safari.app/Contents/MacOS/Safari


COLUMN 'First Observed', 'Last Observed', 'PID', 'Command Line' SELECT FIRST(startTime),
LAST(startTime), FIRST(pid), FIRST(commandLine) FROM SystemProcess GROUP BY pid

Execution: query-validation=10.6 ms, aggregation=241 ms, formatting=121 ms

As we can see, the verbose command generates more information about the system processes including some meta information such as an explanation of the query and execution statistics to see how long it took.

我们可以看到,verbose 命令会生成更多有关系统进程的信息,包括一些元信息,如查询解释和执行统计信息,以了解查询所需的时间。

6.4. Comparing the Result With JCM

6.4.与 JCM 的结果比较

The JFR view Command is an attempt to make the process of analyzing JFR recordings easier and independent of any additional tool. The JMC visual output and the console-based output of the view command are quite similar. We can compare the result of the system-processes view with that of the visual JMC tool:

JFRview命令试图使分析 JFR 记录的过程变得更简单,并且不依赖于任何其他工具view 命令的 JMC 可视化输出和基于控制台的输出非常相似。我们可以将 system-processes 视图的结果与 JMC 可视化工具的结果进行比较:

JMC view showing the processes running in the system

7. Conclusion

7.结论

In this article, we looked at the newly added JFR view command that assists in displaying the results of the Java flight recordings directly in the command line with a set of predefined views. We saw the different categories of views available today and the ways we can generate a view for our flight recordings.

在本文中,我们了解了新添加的 JFR view 命令,该命令可通过一组预定义视图在命令行中直接显示 Java 飞行记录的结果。我们了解了目前可用的不同视图类别,以及为飞行记录生成视图的方法。

As usual, the source code from this article can be found over on GitHub.

与往常一样,本文的源代码可以在 GitHub 上找到