Java 21 中的 JFR 檢視指令
一、簡介
Java Flight Recorder (JFR) 是一種分析和診斷工具,用於監控 JVM 及其上執行的程式。它是開發人員用來監控應用程式的狀態和效能的便捷分析工具。
本教程將重點放在 Java 21 中為 JFR 引入的新view
指令。
2.Java飛行記錄器(JFR)
Java Flight Recorder (JFR) 是一個低開銷的應用程式分析框架,作為實驗性功能在 Java 7 中引入。它使我們能夠分析和理解有關程序的重要指標,例如垃圾收集模式、IO 操作、記憶體分配等。
2.1.什麼是 Java 飛行記錄器?
當 Java 應用程式運行時,JFR 收集有關 JVM 中事件的信息,並使用診斷工具分析結果。
JFR 監視應用程式並將分析結果記錄在記錄檔中。我們可以透過兩種方式指示 JFR 監控應用程式:
- 使用命令列啟動應用程式並啟用 JFR。
- 在已執行的 Java 應用程式上使用
jcmd
等診斷工具。
記錄通常會產生為.jfr
文件,然後可以透過視覺化工具(例如 Java Mission Control (JMC) 工具)或使用新的view
命令(我們將在接下來的部分中看到)進行分析。
2.2.從命令列錄製
為了示範飛行記錄,讓我們寫一個小程序,將一個物件插入到ArrayList
中,直到拋出OutOfMemoryError
:
void insertToList(List<Object> list) {
try {
while (true) {
list.add(new Object());
}
} catch (OutOfMemoryError e) {
System.out.println("Out of Memory. Exiting");
}
}
讓我們使用標準javac
編譯器來編譯該程式:
javac -d out -sourcepath JFRExample.java
產生.class
檔案後,我們啟動飛行記錄器。我們向java
指令傳遞一些附加參數,即-XX:+FlightRecorder
選項,以及一些附加參數來設定錄製持續時間和儲存錄製的輸出檔案路徑:
java -XX:StartFlightRecording=duration=200s,filename=flight.jfr -cp ./out/ com.baeldung.jfrview.JFRExample
我們的程式現在在啟用 JFR 的情況下運行,以捕獲事件和其他系統屬性,並且 JFR 將結果寫入到flight.jfr
檔案中。
2.3.使用jcmd
工具錄製
jcmd
診斷工具提供了另一種記錄和分析應用程式和 JVM 效能的方法。我們可以使用此工具將診斷事件註冊到正在執行的虛擬機器。
要使用jcmd
工具,我們需要運行應用程式並且必須知道pid
:
jcmd <pid|MainClass> <command> [parameters]
jcmd
工具識別的幾個命令是:
- JFR.start – 開始新的 JFR 錄製
- JFR.check – 檢查正在運行的 JFR 記錄
- JFR.stop – 停止特定的 JFR 錄製
- JFR.dump – 將 JFR 記錄的內容複製到文件
這些命令中的每一個都需要附加參數。
現在讓我們使用jcmd
工具建立一個錄音。我們需要啟動應用程式並找到正在運行的進程的pid
。一旦我們有了pid
,我們就開始記錄:
jcmd 128263 JFR.start filename=recording.jfr
當我們捕捉到相關事件後,我們可以停止錄製:
jcmd 128263 JFR.stop filename=recording.jfr
3. 查看JFR錄音文件
要查看和了解jfr
檔案的結果,我們可以使用 Java Mission Control (JMC) 工具。 JMC 工具具有許多功能來分析和監視 Java 應用程序,包括讀取 JFR 檔案並顯示結果的可視化表示的診斷工具:
jfr
命令
jfr
指令解析飛行記錄檔 ( .jfr
) 並將其列印到標準輸出。雖然我們之前使用任務控制工具進行視覺化表示,但jfr
命令為我們提供了一種從控制台中的飛行記錄檔案過濾、總結和生成人類可讀輸出的方法。
4.1.使用jfr
命令
jfr
指令駐留在$JAVA_HOME
的bin
路徑中。我們來看看它的語法:
$JAVA_HOME/bin/jfr [command] <path>
在以下部分中,我們將直接存取jfr
。
4.2. jfr
命令
jfr
以前有五個指令,分別是print
、 summary
、 metadata,
assemble,
和disassemble
。 view
指令是已引入的第六個jfr
指令。
print
指令用來列印飛行記錄的內容,它需要幾個參數,包括輸出格式( json
/ xml
等)、一系列篩選器(可能包括類別、事件和堆疊深度):
jfr print [--xml|--json] [--categories <filters>] [--events <filters>] [--stack-depth <depth>] <file>
顧名思義, summary
指令會產生記錄摘要,其中包括發生的事件、磁碟空間實用程式等:
jfr summary <file>
metadata
命令產生有關事件的詳細信息,例如事件的名稱和類別:
jfr metadata <file>
最後, assemble
和disassemble
命令用於將區塊文件組裝成記錄文件,反之亦然:
jfr assemble <repository> <file>
jfr disassemble [--max-chunks <chunks>] [--output <directory>] <file>
4.3. jfr
命令範例
現在我們將看一個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. JDK 21中的view
指令
Java 21 引入了view
命令,以方便從命令列分析 JFR 記錄。這個新的view
指令無需將錄音下載轉儲到 JMC 工具中,並附帶 70 多個預建選項。這些選項可能會隨著時間的推移而增加,幾乎涵蓋了應用程式的所有重要方面,包括 JVM、應用程式本身以及應用程式的環境。
5.1.查看選項的類別
我們可以將不同的view
選項大致分為三類,與 JMC 工具中顯示的選項類似:
- Java 虛擬機器視圖
- 環境景觀
- 應用程式視圖
5.2. JVM 視圖
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.環境景觀
環境視圖顯示有關運行 JVM 的主機系統的信息,例如 CPU 資訊、網路使用率、系統屬性、進程和資訊。一些常見的環境視圖是:
-
cpu-information
-
cpu-load
-
jvm-flags
-
container-configuration
-
network-utilization
-
system-processes
-
system-properties
5.4.應用程式視圖
應用程式視圖提供對應用程式程式碼的深入了解,例如有關其線程使用情況、物件統計資訊和記憶體利用率的資訊。一些常見的應用程式視圖包括:
-
exception-count
-
object-statistics
-
allocation-by-thread
-
memory-leaks-by-class
-
thread-cpu-load
-
thread-count
-
thread-allocation
5.5. view
的命令結構
view
指令需要視圖名稱和記錄文件的路徑以及相關參數。可以使用jfr
指令和jcmd
指令來啟動它:
jfr view [view] <recording file>
jcmd <pid> JFR.view [view name]
然後輸出顯示在命令列或任何標準輸出上。此外,這些命令還提供輸出格式、時間範圍和自訂視圖的自訂功能。
6. JFR view
命令用法
在本節中,我們將使用view
命令和上一節中提到的一些視圖來分析我們先前產生的 JFR 記錄檔。
6.1.使用jfr
命令
讓我們使用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
顧名思義,該視圖會產生有關正在使用的 GC 類型的信息以及有關垃圾收集的其他相關數據。
6.2.使用jcmd
工具
我們也可以將view
指令與jcmd
工具一起使用:
jcmd <pid> JFR.view [view name]
jcmd
工具需要一個正在運行的 pid 來診斷,我們將請求環境視圖system-processes
:
jcmd 37417 JFR.view cell-height=3 truncate=beginning width=80 system-processes
6.3.格式化iew
命令輸出
我們可以使用view
命令的輸出並根據我們的需求進行調整。 view
命令目前提供了多個選項來格式化輸出,包括修改列數和行數,以及其他選項,例如詳細標誌和輸出截斷:
--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]
舉個例子,讓我們格式化上面產生的系統進程視圖的輸出,使每行有兩行,並使回應變得詳細:
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
正如我們所看到的,詳細命令生成有關係統進程的更多信息,包括一些元信息,例如查詢的解釋和執行統計信息以了解花費了多長時間。
6.4.與 JCM 的結果比較
JFR view
指令試圖使 JFR 記錄的分析過程變得更加簡單,並且獨立於任何其他工具。 JMC 視覺化輸出和view
指令基於控制台的輸出非常相似。我們可以將system-processes
視圖的結果與視覺化 JMC 工具的結果進行比較:
七、結論
在本文中,我們研究了新新增的 JFR view
命令,該命令有助於透過一組預定義視圖直接在命令列中顯示 Java 飛行記錄的結果。我們看到了今天可用的不同類別的視圖以及我們為飛行記錄生成視圖的方法。
與往常一樣,本文的源代碼可以在 GitHub 上找到。