OpenJDK での JDK フライトレコーダーの使用

OpenJDK 17

ガイド

概要

OpenJDKguide での JDK フライトレコーダーの使用ガイドでは、JDK フライトレコーダー (JFR) および JDK Mission Control (JMC) の概要と、JFR の起動方法を説明します。

多様性を受け入れるオープンソースの強化

Red Hat では、コード、ドキュメント、Web プロパティーにおける配慮に欠ける用語の置き換えに取り組んでいます。まずは、マスター (master)、スレーブ (slave)、ブラックリスト (blacklist)、ホワイトリスト (whitelist) の 4 つの用語の置き換えから始めます。この取り組みは膨大な作業を要するため、今後の複数のリリースで段階的に用語の置き換えを実施して参ります。詳細は、弊社の CTO、Chris Wright のメッセージ を参照してください。

Red Hat ドキュメントへのフィードバック

弊社のドキュメントに関するご意見やご感想をお寄せください。フィードバックをお寄せいただくには、ドキュメントのテキストを強調表示し、コメントを追加できます。

本セクションでは、フィードバックの送信方法を説明します。

前提条件

  • Red Hat カスタマーポータルにログインしている。
  • Red Hat カスタマーポータルで、マルチページ HTML 形式でドキュメントを表示します。

手順

フィードバックを提供するには、以下の手順を実施します。

  1. ドキュメントの右上隅にある フィードバック ボタンをクリックして、既存のフィードバックを確認します。

    注記

    フィードバック機能は、マルチページ HTML 形式でのみ有効です。

  2. フィードバックを提供するドキュメントのセクションを強調表示します。
  3. ハイライトされたテキスト近くに表示される Add Feedback ポップアップをクリックします。

    ページの右側のフィードバックセクションにテキストボックスが表示されます。

  4. テキストボックスにフィードバックを入力し、Submit をクリックします。

    ドキュメントに関する問題が作成されます。

  5. 問題を表示するには、フィードバックビューで問題トラッカーリンクをクリックします。

第1章 JDK フライトレコーダーの概要

他のアプリケーションはこれらのファイルを分析に使用できます。

1.1. JDK Flight Recorder (JFR) コンポーネント

JFR 機能を使用して、JVM 内で実行されるイベントを監視し、これらの監視されたイベントから収集されたデータから記録を作成できます。

次のリストは、主要な JFR 機能の詳細です。

記録
システムの記録を管理できます。各記録には固有の設定があります。録画を開始または停止したり、オンデマンドでディスクに保存したりできます。
イベント

イベントまたはカスタムイベントを使用して Java アプリケーションのデータとメタデータをトレースし、いずれかのイベントタイプのデータとメタデータを JFR ファイルに保存できます。Java Mission Control (JMC)、jcmd などのさまざまなツールを使用して、JFR ファイルに格納されている情報を表示および分析できます。

Java Virtual Machine (JVM) には、継続的に追加された既存のイベントが多数含まれています。ユーザーがカスタムイベントをアプリケーションに注入するために API を使用できます。

イベント設定を指定してオーバーヘッドを最小限に抑える場合は、記録時にイベントを有効または無効にできます。これらの設定は xml ドキュメントの形式を取り、JFR プロファイル (*.jfc) と呼ばれます。OpenJDK には、最も一般的なユースケースでは以下の 2 つのプロファイルがあります。

  • default: デフォルト のプロファイルは、実稼働環境で継続的に使用する場合に安全な低オーバーヘッド設定です。通常、オーバーヘッドは 1% 未満です。
  • profile: プロファイルプロファイル は、プロファイリングに適する低オーバーヘッド設定です。通常、オーバーヘッドは 2% 未満です。

1.2. JDK フライトレコーダーを使用する利点

JDK フライトレコーダー (JFR) を使用する主な利点には、以下が含まれます。

  • JFR は実行中の JVM で記録できます。アプリケーションの再起動または再ビルドが難しい本番環境では、JFR を使用する方が適しています。
  • JFR では、カスタムイベントとメトリクスの定義を監視することができます。
  • JFR は JVM に組み込まれ、パフォーマンスのオーバーヘッドを最小限に抑えることができます (約 1%)。
  • JFR は、一貫したデータモデルを使用して、イベントの境界およびデータのフィルタリングを向上させます。
  • JFR を使用すると、API を使用したサードパーティーのアプリケーションの監視が可能になります。
  • JFR は、以下を行います。

    • 時間を費やす。
    • 問題のトラブルシューティングに役立ちます。
  • JFR は、以下の操作コストとビジネス中断を削減します。

    • 解決時間を短縮する時間を提供します。
    • パフォーマンスの問題を特定し、システム効率を向上するのに役立ちます。

第2章 JDK Mission Control の概要

これには、JMC イベントを出力する詳細ビューおよびグラフが含まれます。

  • JMX Console MBean
  • HPROF-dump analyzer

JMC は Eclipse プラットフォームに基づいています。

2.1.

前提条件

手順

  1. # sudo yum module install jmc:rhel8/common

    1. $ jmc -vm /usr/lib/jvm/java-11/bin/java

関連情報

2.2.

重要

注記

2.3.

前提条件

注記

手順

    1. 注記

  1. 図2.1

  2. 注記

  3. 図2.2

    図2.3

2.4.

前提条件

手順

  1. 図2.4

  2. 図2.5

    1. ヒント

  3. 図2.6

  4. 以下に例を示します。

    図2.7

関連情報

2.5.

表2.1

 説明

表2.2

 説明

表2.3

 説明

表2.4

 説明

第3章 JDK フライトレコーダーの起動

3.1. JVM の起動時に JDK フライトレコーダーの起動

Java プロセスの開始時に、JDK フライトレコーダー (JFR) を開始できます。JFR の動作を変更するには、オプションのパラメーターを追加します。

手順

  • --XX オプションを使用して java コマンドを実行します。

    $ java -XX:StartFlightRecording Demo

    Demo は、Java アプリケーションの名前に置き換えます。

    JFR は Java アプリケーションから始まります。

以下のコマンドでは、Java プロセス (Demo) を開始し、1 時間の長さのフライトレコーの録画を開始して、demorecording.jfr という名前のファイルに保存されます。

$ java -XX:StartFlightRecording=duration=1h,filename=demorecording.jfr Demo

関連情報

  • JFR オプションの詳細なリストは、「Java tools reference」を参照してください。

3.2. 実行中の JVM での JDK フライトレコーダーの開始

jcmd ユーティリティーを使用して、診断コマンド要求を実行中の JVM に送信できます。jcmd には、startdumpstop などの最も基本的なコマンドとともに、JFR との対話のコマンドが含まれます。

JVM と対話するには、jcmd に JVM のプロセス ID (pid) が必要です。実行中の JVM プロセス ID のリストを表示する jcmd -l コマンドと、プロセスの起動に使用したメインクラスやコマンドライン引数などの情報を表示することで取得できます。

jcmd ユーティリティーは $JAVA_HOME/bin にあります。

手順

  • 以下のコマンドを使用して、フライトレコーディングを開始します。

    $ jcmd <pid> JFR.start <options>

    たとえば、以下のコマンドは demorecording という名前の録画を開始します。これは過去 4 時間のデータを保持し、サイズが 400 MB の録画になります。

    $ jcmd <pid> JFR.start name=demorecording maxage=4h maxsize=400MB

関連情報

3.3.

JDK Mission Control (JMC)アプリケーションにはフライトレコーダーがあります。これにより、フライトレコーティングを開始および設定できるシンプルな操作が可能になります。

手順

  1. JVM ブラウザーを開きます。

    $ JAVA_HOME/bin/jmc

  2. JVM ブラウザービューで JVM を右クリックし、Start Flight Recording を選択します。

    フライトレコーウィザードが開きます。

    図3.1 JMC JFR ウィザード

    jmc jfrwizard 2

    JDK Flight Recording Wizard には 3 つのページがあります。

    • ウィザードの最初のページには、以下を含む移動記録の一般的な設定が含まれています。

      • 記録の名前
      • 記録の保存先のパスおよびファイル名
      • 録画が固定された時間または継続的な録画であるか。イベントテンプレートが使用されます。
      • 録画の説明
    • 2 番目のページには、フライトレコーのイベントオプションが含まれます。Garbage Collections、Memory Profiling、および Method Sampling およびその他のイベントレコードの詳細レベルを設定できます。
    • 3 番目のページには、イベントの詳細の設定が含まれます。イベントをオンにまたはオフにし、スタックトレースの記録を有効にし、イベントの記録に必要な時間しきい値を変更できます。
  3. 記録の設定を編集します。
  4. Finish をクリックします。

    ウィザードは終了し、移動の記録が開始されます。

3.4.

手順

  1. @Name(“SampleCustomEvent”)
    public class SampleCustomEvent extends Event {...}

  2. 注記

    @Name(“SampleCustomEvent”)  1
    @Label("Sample Custom Event")
    @Category("Sample events")
    @Description("Custom Event to demonstrate the Custom Events API")
    @StackTrace(false) 2
    public class SampleCustomEvent extends Event {
    
    
        @Label("Method") 3
        public String method;
    
    
        @Label("Generated Number")
        public int number;
    
    
        @Label("Size")
        @DataAmount 4
        public int size;
    }

    1
    2
    3
    4
  3. public class Main {
    
    	private static int requestsSent;
    
    	public static void main(String[] args) {
        	// Register the custom event
        	FlightRecorder.register(SampleCustomEvent.class);
        	// Do some work to generate the events
        	while (requestsSent <= 1000) {
            	try {
                	eventLoopBody();
                	Thread.sleep(100);
            	} catch (Exception e) {
                	e.printStackTrace();
            	}
        	}
        }
    
    	private static void eventLoopBody() {
        	// Create and begin the event
        	SampleCustomEvent event = new SampleCustomEvent();
        	event.begin();
        	// Generate some data for the event
        	Random r = new Random();
        	int someData = r.nextInt(1000000);
        	// Set the event fields
        	event.method = "eventLoopBody";
        	event.number = someData;
        	event.size = 4;
        	// End the event
        	event.end();
        	event.commit();
        	requestsSent++;
        }

  4. 図3.2

関連情報

第4章 JDK フライトレコーダーの設定オプション

コマンドラインまたは診断コマンドを使用して、JDK Flight Recorder (JFR) を設定して、さまざまなイベントセットをキャプチャーできます。

4.1. コマンドラインを使用した JDK フライトレコーダーの設定

以下のオプションを使用すると、コマンドラインから JDK フライトレコーダー (JFR) を設定できます。

4.1.1. JFR の起動

-XX:StartFlightRecording オプションを使用して、Java アプリケーションの JFR の録画を開始します。以下に例を示します。

java -XX:StartFlightRecording=delay=5s,disk=false,dumponexit=true,duration=60s,filename=myrecording.jfr <<YOUR_JAVA_APPLICATION>>

JFR 録画の開始時に、以下の parameter=value エントリーを設定できます。

delay=time
このパラメーターを使用して、Java アプリケーションの起動時間から録画の開始までの遅延を指定します。時間で (秒の場合は s)、分 (分の場合は m)、h (日の場合は d) を指定する場合には s を追加します。たとえば、10m を指定すると 10 分になります。デフォルトでは遅延がなく、このパラメーターは 0 に設定されます。
disk={true|false}
このパラメーターを使用して、録画中にディスクにデータを書き込むかどうかを指定します。デフォルトでは、このパラメーターは true です。
dumponexit={true|false}
このパラメーターを使用して、JVM シャットダウン時に実行中の録画がダンプされるかどうかを指定します。パラメーターが有効になり、ファイル名が設定されていない場合、録画の進捗は、録画の進捗が開始されたディレクトリー内のファイルに記録が書き込まれます。ファイル名は、プロセス ID、記録 ID、および現在のタイムスタンプを含むシステム生成名です。例: hotspot-pid-47496-id-1-2018_01_25_19_10_41.jfrデフォルトでは、このパラメーターは false です。
duration=time
このパラメーターを使用して、記録期間を指定します。時間で (秒の場合は s)、分 (分の場合は m)、h (日の場合は d) を指定する場合には s を追加します。たとえば、期間を 5h に指定した場合は、5 時間を示します。デフォルトでは、このパラメーターは 0 に設定されています。これは、録画期間に無制限を意味します。
filename=path

このパラメーターを使用して、録画ファイルのパスと名前を指定します。停止時にこのファイルに記録が書き込まれます。以下に例を示します。

IncomeSource recording.jfr

· /home/user/recordings/recording.jfr

name=identifier
このパラメーターを使用して、記録の名前と録画の識別子を指定します。
maxage=time
このパラメーターを使用して、ディスク上で録画可能な最大日数を指定します。このパラメーターは、disk パラメーターが true に設定されている場合にのみ有効です。時間で (秒の場合は s)、分 (分の場合は m)、h (日の場合は d) を指定する場合には s を追加します。たとえば、30s を指定する場合、これは 30 秒を示します。デフォルトでは、このパラメーターは 0 に設定されています。これは、制限が設定されていないことを意味します。
maxsize=size
このパラメーターを使用して、録画用に保持するディスクデータの最大サイズを指定します。このパラメーターは、disk パラメーターが true に設定されている場合にのみ有効です。この値は、-XX:FlightRecorderOptions で設定した maxchunksize パラメーターの値よりも大きくすることはできません。サイズをメガバイト単位で指定する場合は m または M を追加するか、サイズがギガバイトで指定する g または G を指定します。デフォルトでは、ディスクデータの最大サイズは制限されず、このパラメーターは 0 に設定されます。
path-to-gc-roots={true|false}

このパラメーターを使用して、録画の最後でガベッジコレクション (GC) ルートへのパスを収集するかどうかを指定します。デフォルトでは、このパラメーターは false に設定されます。

GC ルートへのパスは、メモリーリークを見つけるのに便利です。OpenJDK 17 では、ヒープダンプの使用よりも効率的であり、古い ObjectSample イベントを有効にできます。実稼働環境で OldObjectSample イベントを使用することもできます。メモリーリーク情報の収集には時間がかかり、追加のオーバーヘッドが発生します。このパラメーターは、メモリーリークがあるアプリケーションの録画を開始する場合にのみ有効にする必要があります。JFR プロファイルパラメーターがプロファイルに設定されている場合、オブジェクトのリークが発生した場所からスタックを追跡できます。収集された情報に含まれます。

settings=path
このパラメーターを使用して、イベント設定ファイルのパスおよび名前を指定します (JFC のタイプは JFC)。デフォルトでは、JAVA_HOME/lib/jfr にある default.jfc ファイルが使用されます。このデフォルト設定ファイルはオーバーヘッドが低い事前定義の情報を収集するため、パフォーマンスへの影響が最小限であり、継続して実行される記録に使用できます。2 番目の設定ファイルも提供されています。profile.jfc はデフォルト設定よりも多くのデータを提供しますが、オーバーヘッドが増え、パフォーマンスに影響を与える可能性があります。詳細情報が必要な場合に短い期間にこの設定を使用します。
注記

複数のパラメーターの値をカンマで区切ります。例: -XX:StartFlightRecording=disk=falsename=example-recording

4.1.2. JFR の動作の制御

-XX:FlightRecorderOptions オプションを使用して、JFR の動作を制御するパラメーターを設定します。以下に例を示します。

java -XX:FlightRecorderOptions=duration=60s,filename=myrecording.jfr -XX:FlightRecorderOptions=stackdepth=128,maxchunksize=2M <<YOUR_JAVA_APPLICATION>>

以下の parameter=value エントリーを設定して、JFR の動作を制御できます。

globalbuffersize=size
このパラメーターを使用して、データの保持に使用するプライマリーメモリーの合計量を指定します。デフォルト値は、memorysize に指定された値に基づいています。memorysize パラメーターを変更して、グローバルバッファーのサイズを変更できます。
maxchunksize=size
このパラメーターを使用して、データチャンクの最大サイズを指定します。サイズをメガバイト単位 (MB) で指定する場合は m または M を追加するか、サイズがギガバイト (GB) で指定する g または G を指定します。デフォルトでは、データチャンクの最大サイズは 12 MB に設定されています。許可される最小値は 1 MB です。
memorysize=size
このパラメーターを使用して、使用するバッファーメモリー容量を決定します。このパラメーターは、指定したサイズに基づいて globalbuffersize パラメーターおよび numglobalbuffers パラメーターを設定します。サイズをメガバイト単位 (MB) で指定する場合は m または M を追加するか、サイズがギガバイト (GB) で指定する g または G を指定します。デフォルトでは、メモリーサイズは 10 MB に設定されています。
numglobalbuffers=number
このパラメーターを使用して、使用されるグローバルバッファーの数を指定します。デフォルト値は、memorysize パラメーターで指定したサイズに基づいています。memorysize パラメーターを変更して、グローバルバッファーの数を変更できます。
old-object-queue-size=number-of-objects
このパラメーターを使用して、古いオブジェクトの最大数を追跡します。デフォルトでは、オブジェクト数は 256 に設定されます。
repository=path
このパラメーターを使用して、一時ディスクストレージのリポジトリーを指定します。デフォルトでは、システムの一時ディレクトリーを使用します。
retransform={true|false}
このパラメーターを使用して、JVMTI を使用してイベントクラスを再変換するかどうかを指定します。false に設定すると、読み込まれたイベントクラスにインストルメンテーションが追加されます。デフォルトでは、クラスの再変換を有効にするには、このパラメーターを true に設定します。
samplethreads={true|false}
このパラメーターを使用して、スレッドサンプリングを有効にするかどうかを指定します。スレッドサンプリングは、サンプリングイベントが有効で、このパラメーターが true に設定されている場合にのみ発生します。デフォルトでは、このパラメーターは true に設定されます。
stackdepth=depth
このパラメーターを使用して、スタックトレースのスタック深度を設定します。デフォルトでは、スタックの深さは 64 メソッド呼び出しに設定されます。スタックの最大深さを 2048 に設定できます。64 を超える値は、大きなオーバーヘッドを作成し、パフォーマンスが低下する可能性があります。
threadbuffersize=size
このパラメーターを使用して、スレッドのローカルバッファーサイズを指定します。デフォルトでは、ローカルバッファーサイズは最低 4 キロバイトの 8 キロバイトに設定されます。このパラメーターを上書きすると、パフォーマンスが低下する可能性があるため、推奨されません。
注記

複数のパラメーターの値をカンマで区切ります。

4.2. 診断コマンド (JCMD) を使用した JDK フライトレコーダーの設定

Java 診断コマンドを使用して、JDK Flight Recorder (JFR) を設定できます。診断コマンドを実行する最も簡単な方法は、Java インストールディレクトリーにある jcmd ツールを使用する方法です。このコマンドを使用するには、JVM のプロセス識別子またはメインクラスの name と、実際のコマンドを jcmd への引数として渡す必要があります。引数なしで jcmd を実行するか、jps を使用して JVM またはメインクラスの名前を取得できます。jps(Java Process Status) ツールは、アクセス権限のあるターゲットシステムの JVM を一覧表示します。

実行中の Java プロセスの一覧を表示するには、引数を指定せずに jcmd コマンドを使用します。実行中の Java アプリケーションで利用可能なコマンドの完全な一覧を表示するには、プロセス ID またはメインクラスの名前の後に診断コマンドとして help を指定します。

JFR で以下の診断コマンドを使用します。

4.2.1. JFR の起動

JFR.start diagnostic コマンドを使用して、フライトの録画を開始します。以下に例を示します。

jcmd <PID> JFR.start delay=10s duration=10m filename=recording.jfr

表4.1 以下の表には、このコマンドで使用できるパラメーターをまとめています。

パラメーター説明データ型デフォルト値

name

記録の名前

文字列

-

settings

サーバー側テンプレート

文字列

-

duration

記録期間

時間

0s

filename

生成される記録ファイル名

文字列

-

maxage

バッファーデータの最大期間

時間

0s

maxsize

バッファーの最大サイズ (バイト単位)

Long

0

dumponexit

JVM シャットダウン時のダンプ実行の記録

ブール値

-

path-to-gc-roots

ガベッジコレクタールートへの収集パス

ブール値

False

4.2.2. JFR の停止

JFR.stop diagnostic コマンドを使用して、フライトレコーの録画を停止します。以下に例を示します。

jcmd <PID> JFR.stop name=output_file

表4.2 以下の表には、このコマンドで使用できるパラメーターをまとめています。

パラメーター説明データ型デフォルト値

name

記録の名前

文字列

-

filename

録画データをファイルにコピーします。

文字列

-

4.2.3. JFR のチェック

JFR.check コマンドを使用して、進行中の録画に関する情報を表示します。以下に例を示します。

jcmd <PID> JFR.check

表4.3 以下の表には、このコマンドで使用できるパラメーターをまとめています。

パラメーター説明データ型デフォルト値

name

記録の名前

文字列

-

filename

録画データをファイルにコピーします。

文字列

-

maxage

ダンプファイルの最大サイズ

時間

0s

maxsize

ダンプする最大バイト数

Long

0

begin

データのダンプ開始

文字列

-

end

データをダンプする終了時間

文字列

-

path-to-gc-roots

ガベッジコレクタールートへの収集パス

ブール値

false

4.2.4. JFR のダンプ

JFR.dump diagnostic コマンドを使用して、フライト録画のコンテンツをファイルにコピーします。以下に例を示します。

jcmd <PID> JFR.dump name=output_file filename=output.jfr

表4.4 以下の表には、このコマンドで使用できるパラメーターをまとめています。

パラメーター説明データ型デフォルト値

name

記録の名前

文字列

-

filename

録画データをファイルにコピーします。

文字列

-

maxage

ダンプファイルの最大サイズ

時間

0s

maxsize

ダンプする最大バイト数

Long

0

begin

データのダンプ開始

文字列

-

end

データをダンプする終了時間

文字列

-

path-to-gc-roots

ガベッジコレクタールートへの収集パス

ブール値

false

4.2.5. JFR の設定

JFR.configure diagnostic コマンドを使用して、フライトの録画を設定します。以下に例を示します。

jcmd <PID> JFR.configure repositorypath=/home/jfr/recordings

表4.5 以下の表には、このコマンドで使用できるパラメーターをまとめています。

パラメーター説明データ型デフォルト値

repositorypath

リポジトリーのパス

文字列

-

dumppath

ダンプのパス

文字列

-

stackdepth

スタックの深さ

Jlong

64

globalbuffercount

グローバルバッファーの数

Jlong

32

globalbuffersize

グローバルバッファーのサイズ

Jlong

524288

thread_buffer_size

スレッドバッファーのサイズ

Jlong

8192

memorysize

全体的なメモリーサイズ

Jlong

16777216

maxchunksize

個々のディスクチャンクのサイズ

Jlong

12582912

Samplethreads

スレッドサンプリングの有効化

ブール値

true