ネイティブ・イメージでのJDK Flight Recorder (JFR)

JDK Flight Recorder (JFR)は、GraalVMネイティブ・イメージによって現在サポートされている本番時のプロファイリング・システムです。

基本的に、-H:+AllowVMInspectionを使用して構築されたネイティブ・イメージは、Javaで記述されたJFRイベントをサポートしており、ユーザーは、Java HotSpot VMでJFRを使用する場合と同様に、引き続きjdk.jfr.Event APIとJFR自体を使用できます。ただし、実行時にJFRイベントを記録するには、JFRサポートおよびJFR記録を有効にする必要があり、このページでは、ネイティブ・イメージでのJFRの使用を開始する方法について説明します。

現在の制限事項

現時点では、JFRサポートは依然として制限されています。つまり、ほとんどのVM内部イベントや、スタック・トレースやメモリー・リーク検出などの高度な機能が不足しています。現在、JFR機能のサブセット(カスタム・イベントとシステム・イベント、ディスク・ベースの記録)を使用できます。現在、JFRはGraalVM JDK 11でビルドされたネイティブ・イメージでのみサポートされています。

JFRによるネイティブ・イメージのビルドおよび実行

JFRイベント・サポートを含むネイティブ・イメージをビルドするには、最初にイメージ・ビルド時にJFRを含める必要があります。これを行うには、-H:+AllowVMInspectionフラグを使用してイメージをビルドします:

native-image -H:+AllowVMInspection JavaApplication

JFRを含むネイティブ・イメージの場合、次のステップは、システムを使用可能にし、記録を開始し、実行時のロギングを構成することです。そのために、次のフラグを使用できます:

JFRを有効にして記録を開始するには、-XX:+FlightRecorder-XX:StartFlightRecordingを一緒に使用します。たとえば:

./javaapplication -XX:+FlightRecorder -XX:StartFlightRecording="filename=recording.jfr"

デモの実行

この非常に単純なデモ・アプリケーションをネイティブ・イメージに変換し、そこでJFRイベントを使用する方法を確認します。次のコードをExample.javaファイルに保存します。

import jdk.jfr.Event;
import jdk.jfr.Description;
import jdk.jfr.Label;

public class Example {

  @Label("Hello World")
  @Description("Helps programmer getting started")
  static class HelloWorldEvent extends Event {
      @Label("Message")
      String message;
  }

  public static void main(String... args) {
      HelloWorldEvent event = new HelloWorldEvent();
      event.message = "hello, world!";
      event.commit();
  }
}

アプリケーションは、1つの単純なクラスといくつかのJDKライブラリ・クラスで構成されます。これは、@Label注釈のラベルが付いたイベントをjdk.jfr.*パッケージから作成します。このアプリケーションを実行すると、何も出力されず、そのイベントが実行されるだけです。

  1. Javaファイルをコンパイルします:
      javac Example.java
    
  2. VM検査を有効にしてネイティブ・イメージにアプリケーションをビルドします:
      native-image -H:+AllowVMInspection Example
    

    -H:+AllowVMInspectionオプションによって、VMの検査に使用できるJFRなどのオプション機能が有効になります。

  3. 実行可能ファイルを実行し、記録を開始します:
      ./example -XX:+FlightRecorder -XX:StartFlightRecording="filename=recording.jfr"
    

    -XX:+FlightRecorderフラグによって、組込みフライト・レコーダが有効になり、指定したファイルへの記録が開始されます。recording.jfrファイルはバイナリです。

  4. VisualVMを起動します。「File」「Add JFR Snapshot」に移動し、生成されたファイルrecording.jfrを参照して開きます。

開くと、モニタリング、スレッド、例外など、チェックできるいくつものオプションが表示されますが、イベントの参照を確認することをお薦めします。次のようになります:

この後の項では、記録を構成する方法またはロギングを有効にする方法について学習します。

記録の構成

-XX:StartFlightRecordingオプションに、キーと値のペアのカンマ区切りのリストを渡して、記録をさらに構成できます。たとえば:

-XX:StartFlightRecording="filename=recording.jfr,dumponexit=true,duration=10s"

次のキーと値のペアがサポートされています:

名前 デフォルト値 説明
name なし 記録の識別に使用できる名前(name=MyRecordingなど)
settings なし 設定ファイル(profile.jfc、default.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) ディスク上に保存するKB(k)、MB(M)またはGB(G)単位の最大バイト数(500Mなど)または制限なしの場合は0。たとえば、maxsize=1G
dumponexit false JVMの停止時に実行中の記録をダンプするかどうか(dumponexit=trueなど)

JFRシステム・ロギングの構成

JFRシステムには、JFRシステムのロギングを構成するための個別のフラグ-XX:FlightRecorderLoggingもあります。使用法は-XX:FlightRecorderLogging=[tag1[+tag2...][*][=level][,...]]です。

たとえば:

-XX:FlightRecorderLogging=jfr,system=debug
-XX:FlightRecorderLogging=all=trace
-XX:FlightRecorderLogging=jfr*=error

使用可能なログ・レベルは、trace、debug、info、warning、error、offです。

使用可能なログ・タグは、all、jfr、system、event、setting、bytecode、parser、metadata、dcmdです。

それ以外の場合、このオプションでは、タグの組合せのカンマ区切りリストが必要で、それぞれにオプションのワイルドカード(*)およびレベルがあります。