搭配原生映像檔的 JDK Flight Recorder (JFR)
JDK Flight Recorder (JFR) 是一個事件記錄器,用於擷取有關 JVM 以及在 JVM 上執行的應用程式的資訊。GraalVM 原生映像檔支援使用 JFR 事件建置原生可執行檔,使用者可以使用 jdk.jfr.Event
API,其體驗類似於在 Java HotSpot VM 中使用 JFR。
在建置時包含 JFR 支援並在執行時記錄事件 #
預設情況下,JFR 支援為停用狀態,必須在建置時明確啟用。
注意:JFR 事件記錄在 Windows 上的 GraalVM JDK 中尚不可用。
若要建置具有 JFR 的原生可執行檔,請使用 --enable-monitoring=jfr
選項
native-image --enable-monitoring=jfr JavaApplication
支援以下選項來啟動記錄,並在執行時設定記錄
-XX:StartFlightRecording
:在應用程式啟動時啟動記錄-XX:FlightRecorderLogging
:設定 JFR 的記錄輸出
若要啟動 JFR 記錄,只需在執行時使用 -XX:StartFlightRecording
即可。例如
./javaapplication -XX:StartFlightRecording="filename=recording.jfr"
設定 JFR 記錄 #
與在 HotSpot 上啟動 JFR 記錄類似,您可以將以逗號分隔的鍵值對清單傳遞給 -XX:StartFlightRecording
選項來啟動記錄。例如
-XX:StartFlightRecording="filename=recording.jfr,dumponexit=true,duration=10s"
支援以下鍵值對
名稱 | 預設值 | 說明 |
---|---|---|
名稱 | 無 | 識別記錄的名稱,例如,name=MyRecording |
設定 | 無 | 設定檔 (profile.jfc、default.jfc 等),例如,settings=myprofile.jfc |
延遲 | 無 | 以 (秒)s、(分)m、(小時)h 或 (天)d 延遲記錄啟動,例如,delay=5h |
期間 | 無限 (0) | 以 (秒)s、(分)m、(小時)h 或 (天)d 為單位的記錄期間,例如,duration=300s |
檔案名稱 | 無 | 產生的記錄檔案名稱,例如,filename=recording1.jfr |
最大年齡 | 無限制 (0) | 在磁碟上保留已記錄資料的最長時間,以 (秒)s、(分)m、(小時)h 或 (天)d 為單位,例如,60m 或 0 表示無限制。例如,maxage=1d |
最大大小 | 無限制 (0) | 在磁碟上保留的最大位元組數,以 (千)kB、(百萬)MB 或 (十億)GB 為單位,例如,500M 或 0 表示無限制。例如,maxsize=1G |
dumponexit | false | 是否在 JVM 關閉時傾印執行中的記錄,例如,dumponexit=true |
設定 JFR 系統記錄 #
您可以使用單獨的旗標 -XX:FlightRecorderLogging
來設定 JFR 系統的記錄。用法為:-XX:FlightRecorderLogging=[tag1[+tag2...][*][=level][,...]]
。例如
-XX:FlightRecorderLogging=jfr,system=debug
-XX:FlightRecorderLogging=all=trace
-XX:FlightRecorderLogging=jfr*=error
- 未設定此選項時,會以
WARNING
層級啟用記錄。 - 當此選項設定為空字串時,會以
INFO
層級啟用記錄。 - 當此選項設定為「disable」時,會完全停用記錄。
可用的記錄層級為:trace、debug、info、warning、error、off
。
可用的記錄標籤為:all、jfr、system、event、setting、bytecode、parser、metadata、dcmd
。
否則,此選項會預期以逗號分隔的標籤組合清單,每個組合都有可選的萬用字元 (*
) 和層級。
- 沒有層級的標籤組合會取得預設的
INFO
層級。 - 如果符合標籤組合的層級,則會記錄具有符合特定標籤組合的標籤的訊息。
- 如果標籤組合沒有萬用字元,則只會比對具有完全相同標籤的訊息。否則,會比對標籤是標籤組合子集的訊息。
- 如果有多個標籤組合符合訊息的標籤,則會套用最右邊的組合。
- 標籤沒有任何符合的標籤組合的訊息會設定為以預設的
WARNING
層級記錄。 - 此選項不區分大小寫。
功能和限制 #
本節概述原生映像檔中可用的 JFR 功能。
方法分析和堆疊追蹤 #
JFR 中的方法分析支援兩種取樣類型:安全點取樣和非同步取樣。非同步取樣器預設為啟用,而安全點取樣器僅在需要時使用。非同步取樣的優點是避免了安全點偏差,如果分析器並未以相同的機率對應用程式中的所有點取樣,就會發生這種情況。在這種情況下,取樣器只能在安全點執行取樣,進而將偏差引入設定檔。
兩種取樣器都會以指定的頻率定期產生 jdk.ExecutionSample
事件。這些範例可以在 JDK Mission Control 或 VisualVM 等應用程式中檢視。此外,在 HotSpot 上支援堆疊追蹤的其他 JFR 事件也支援原生映像檔中的堆疊追蹤。這表示您可以執行有趣的操作,例如檢視 jdk.ObjectAllocationInNewTLAB
的火焰圖,以診斷物件配置頻繁發生的位置。
JFR 事件串流 #
原生映像檔提供 JFR 事件串流。事件串流讓您可以在應用程式層級註冊特定事件的回呼。這會對記錄的管理方式帶來更多彈性和控制。例如,如果發現事件在串流中超出特定次數,您可以動態提高事件的期間臨界值。事件串流也讓應用程式可以取得對監控目的而言很有用的持續定期 JFR 更新。
目前,串流事件上尚無提供堆疊追蹤。這表示您無法在其回呼方法內存取事件的堆疊追蹤。但是,此限制不會影響 JFR 快照檔案 (.jfr) 中的堆疊追蹤,這些仍會照常運作。
透過遠端 JMX 與 FlightRecorderMXBean 互動 #
您可以使用遠端 JMX 連線到 FlightRecorderMXBean
,從程序外部與原生映像檔 JFR 互動。這可以使用 JDK Mission Control 或 VisualVM 等應用程式來完成。透過 JMX,您可以使用 FlightRecorderMXBean
API 作為介面來啟動、停止和傾印 JFR 記錄。
注意:遠端 JMX 連線支援需要在建置時單獨啟用,而且是實驗性的。
FlightRecorderOptions #
您可以在執行時使用 -XX:FlightRecorderOptions
來微調 JFR 參數。這主要是針對進階使用者,大多數人應該可以使用預設參數。
洩漏分析 #
使用 jdk.OldObjectSample
事件實作的洩漏分析部分可用。具體來說,可以追蹤舊物件,但無法提供 GC 根資訊的路徑。
內建事件 #
許多 VM 層級的內建事件都可在原生映像檔中使用。在 HotSpot JVM 上透過位元組碼檢測實作的 Java 層級事件在原生映像檔中尚不可用。這類事件包括檔案 I/O 和例外狀況內建事件。
下表列出可以使用原生映像檔收集的 JFR 事件。某些事件僅在使用 Serial GC 時可用,Serial GC 是原生映像檔中的預設垃圾收集器。
事件名稱 |
---|
jdk.ActiveRecording |
jdk.ActiveSetting |
jdk.AllocationRequiringGC 1) |
jdk.ClassLoadingStatistics |
jdk.ContainerCPUThrottling |
jdk.ContainerCPUUsage |
jdk.ContainerConfiguration |
jdk.ContainerIOUsage |
jdk.ContainerMemoryUsage |
jdk.DataLoss |
jdk.ExecutionSample |
jdk.ExecuteVMOperation |
jdk.GarbageCollection 1) |
jdk.GCHeapSummary 1) |
jdk.GCPhasePause 1) |
jdk.GCPhasePauseLevel1 1) |
jdk.GCPhasePauseLevel2 1) |
jdk.GCPhasePauseLevel3 1) |
jdk.GCPhasePauseLevel4 1) |
jdk.InitialEnvironmentVariable |
jdk.InitialSystemProperty |
jdk.JavaMonitorEnter |
jdk.JavaMonitorInflate |
jdk.JavaMonitorWait |
jdk.JavaThreadStatistics |
jdk.JVMInformation |
jdk.ObjectAllocationSample 1) |
jdk.ObjectAllocationInNewTLAB 1) |
jdk.OldObjectSample 2) |
jdk.OSInformation |
jdk.PhysicalMemory |
jdk.SafepointBegin |
jdk.SafepointEnd |
jdk.SocketRead |
jdk.SocketWrite |
jdk.SystemGC 1) |
jdk.ThreadAllocationStatistics |
jdk.ThreadCPULoad |
jdk.ThreadEnd |
jdk.ThreadPark |
jdk.ThreadSleep |
jdk.ThreadStart |
jdk.VirtualThreadEnd |
jdk.VirtualThreadPinned |
jdk.VirtualThreadStart |
1) 如果使用 Serial GC 則可用。
2) 如果使用 Serial GC 則部分可用。