Native ImageでのJDK Flight Recorder (JFR)

JDK Flight Recorder (JFR) は、JVMとその上で実行されるアプリケーションに関する情報をキャプチャするためのイベントレコーダーです。GraalVM Native Imageは、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 なし 記録を識別するための名前。例えば、name=MyRecording
settings なし 設定ファイル(profile.jfcdefault.jfcなど)。例えば、settings=myprofile.jfc
delay なし 記録開始を(秒)s、(分)m、(時間)h、または(日)dで遅延させます。例えば、delay=5h
duration 無限(0) 記録の持続時間を(秒)s、(分)m、(時間)h、または(日)dで指定します。例えば、duration=300s
filename なし 結果の記録ファイル名。例えば、filename=recording1.jfr
maxage 制限なし(0) 記録されたデータをディスクに保持する最大時間(秒)s、(分)m、(時間)h、または(日)dで指定します。例えば、60m、または制限なしの場合は0。例:maxage=1d
maxsize 制限なし(0) ディスクに保持する最大容量を(k)B、(M)Bまたは(G)Bで指定します。例えば、500M、または制限なしの場合は0。例:maxsize=1G
dumponexit false JVMがシャットダウンしたときに実行中の記録をダンプするかどうか。例えば、dumponexit=true

JFRシステムログの設定 #

JFRシステムのログは、別のフラグ-XX:FlightRecorderLoggingで設定できます。使い方は:-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でログに記録されるように設定されます。
  • このオプションは大文字と小文字を区別しません。

機能と制限事項 #

このセクションでは、Native Imageで利用可能なJFR機能の概要を説明します。

メソッドプロファイリングとスタックトレース #

JFRでのメソッドプロファイリングは、セーフポイントサンプリングと非同期サンプリングの2種類のサンプリングをサポートしています。非同期サンプラーはデフォルトで有効になっており、セーフポイントサンプラーは要求があった場合にのみ使用されます。非同期サンプリングには、プロファイラーがアプリケーション内のすべてのポイントを同じ確率でサンプリングしない場合に発生する、セーフポイントバイアスを回避できるという利点があります。このシナリオでは、サンプラーはセーフポイントでのみサンプリングを実行できるため、プロファイルにバイアスが導入されます。

どちらのサンプラーも、指定された頻度でイベントjdk.ExecutionSampleを定期的に生成します。これらのサンプルは、JDK Mission ControlやVisualVMなどのアプリケーションで表示できます。さらに、HotSpotでスタックトレースをサポートする他のJFRイベントも、Native Imageでスタックトレースをサポートします。つまり、jdk.ObjectAllocationInNewTLABのフレームグラフを表示して、オブジェクトの割り当てが頻繁に発生している場所を診断するなど、興味深いことができます。

JFRイベントストリーミング #

JFRイベントストリーミングは、Native Imageで使用できます。イベントストリーミングを使用すると、アプリケーションレベルで特定のイベントのコールバックを登録できます。これにより、記録の管理方法の柔軟性と制御性が向上します。たとえば、ストリームで特定のイベントが一定回数を超えて検出された場合、そのイベントの期間しきい値を動的に増やすことができます。イベントストリーミングでは、アプリケーションが監視目的で役立つ継続的な定期的なJFR更新を取得することもできます。

現在、スタックトレースはストリーミングされたイベントではまだ利用できません。つまり、コールバックメソッド内でイベントのスタックトレースにアクセスすることはできません。ただし、この制限は、JFRスナップショットファイル(.jfr)のスタックトレースには影響しません。これらは通常どおりに機能します。

リモートJMX経由のFlightRecorderMXBeanとの相互作用 #

FlightRecorderMXBeanへのリモートJMX接続を介して、プロセス外からNative Image JFRと対話できます。これは、JDK Mission ControlやVisualVMなどのアプリケーションを使用して行うことができます。JMXを介して、インターフェースとしてFlightRecorderMXBean APIを使用して、JFR記録を開始、停止、およびダンプできます。

注: リモートJMX接続のサポートは、ビルド時に個別に有効にする必要があり、実験的です。

FlightRecorderOptions #

実行時に-XX:FlightRecorderOptionsを使用して、JFRパラメーターを微調整できます。これは主に高度なユーザー向けであり、ほとんどの人はデフォルトのパラメーターで問題ないはずです。

リークプロファイリング #

jdk.OldObjectSampleイベントを使用して実装されたリークプロファイリングは、部分的に利用可能です。具体的には、古いオブジェクトの追跡は可能ですが、GCルートへのパス情報は利用できません。

組み込みイベント #

多くのVMレベルの組み込みイベントが、Native Imageで利用可能です。HotSpot JVMでのバイトコードインストルメンテーションによって実装されたJavaレベルのイベントは、Native Imageではまだ利用できません。このようなイベントには、ファイルI/Oと例外の組み込みイベントが含まれます。

次の表は、Native Imageで収集できるJFRイベントを一覧表示しています。一部のイベントは、Native Imageのデフォルトのガベージコレクターである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を使用している場合、部分的に使用できます。

参考資料 #

お問い合わせ