1. 概要

このチュートリアルでは、Javaフライトレコーダー、その概念、基本的なコマンド、およびその使用方法について説明します。

2. Java監視ユーティリティ

Javaは単なるプログラミング言語ではなく、多くのツールを備えた非常に豊富なエコシステムです。 JDKには、独自のプログラムをコンパイルしたり、プログラム実行のライフサイクル全体でその状態とJava仮想マシンの状態を監視したりできるプログラムが含まれています。

JDKディストリビューションのbinフォルダーには、特に、プロファイリングと監視に使用できる次のプログラムが含まれています。

  • Java VisualVM (jvisualvm.exe)
  • JConsole (jconsole.exe)
  • Java Mission Control (jmc.exe)
  • 診断コマンドツール(jcmd.exe)

このフォルダの内容を調べて、使用できるツールを確認することをお勧めします。 Java VisualVMは、過去にはOracleおよびOpenJDKディストリビューションの一部であったことに注意してください。 ただし、 Java 9以降、JDKディストリビューションにはJavaVisualVMが付属しなくなりました。 したがって、VisualVMオープンソースプロジェクトのWebサイトとは別にダウンロードする必要があります。

このチュートリアルでは、Javaフライトレコーダーに焦点を当てます。 これはスタンドアロンプログラムではないため、上記のツールには含まれていません。 その使用法は、上記の2つのツール(JavaMissionControlおよびDiagnosticCommandTools)と密接に関連しています。

3. Javaフライトレコーダーとその基本概念

Java Flight Recorder(JFR)は、Javaアプリケーションの実行中にJava仮想マシン(JVM)のイベントに関する情報を収集する監視ツールです。 JFRはJDKディストリビューションの一部であり、JVMに統合されています。

JFRは、実行中のアプリケーションのパフォーマンスにできるだけ影響を与えないように設計されています

JFRを使用するには、JFRをアクティブ化する必要があります。 これは、次の2つの方法で実現できます。

  1. Javaアプリケーションを起動するとき
  2. Javaアプリケーションがすでに実行されているときにjcmdツールの診断コマンドを渡す

JFRにはスタンドアロンツールはありません。 JFRによって収集されたデータを視覚化できるプラグインを含むJavaMissionControl(JMC)を使用します。

これらの3つのコンポーネント( JFR jcmd 、および JMC )は、実行中のJavaプログラムの低レベルのランタイム情報を収集するための完全なスイートを形成します。 この情報は、プログラムを最適化するとき、または問題が発生したときに診断するときに非常に役立つ場合があります。

コンピュータにさまざまなバージョンのJavaがインストールされている場合は、がJavaコンパイラ(java c)、Javaランチャー(java)、および上記のものであることを確認することが重要です。ツール(JFR、jcmd、およびJMC)は、同じJavaディストリビューションからのものです。 そうしないと、異なるバージョンのJFRデータ形式に互換性がない可能性があるため、有用なデータが表示されない可能性があります。

JFRには、イベントとデータフローという2つの主要な概念があります。それらについて簡単に説明します。

3.1. イベント

JFRは、Javaアプリケーションの実行時にJVMで発生するイベントを収集します。 これらのイベントは、JVM自体の状態またはプログラムの状態に関連しています。 イベントには、名前、タイムスタンプ、および追加情報(スレッド情報、実行スタック、ヒープの状態など)があります。

JFRが収集する3種類のイベントがあります。

  • インスタントイベントは、発生するとすぐにログに記録されます
  • 期間イベントは、その期間が指定されたしきい値を超えるとログに記録されます
  • サンプルイベントは、システムアクティビティをサンプリングするために使用されます

3.2. データフロー

JFRが収集するイベントには、膨大な量のデータが含まれています。 このため、設計上、JFRはプログラムを妨げないほど高速です。

JFRは、イベントに関するデータを単一の出力ファイルに保存します。 Flight.jfr。 

ご存知のように、ディスクI/O操作は非常にコストがかかります。 したがって、JFRはさまざまなバッファを使用して、データのブロックをディスクにフラッシュする前に、収集されたデータを保存します。 同時に、プログラムに異なるオプションを持つ複数の登録プロセスがある可能性があるため、状況は少し複雑になる可能性があります。

このため、出力ファイルに要求よりも多くのデータが含まれている場合や、時系列になっていない場合があります。 JMCを使用すると、イベントが時系列で視覚化されるため、この事実に気付かない場合があります。

まれに、JFRがデータのフラッシュに失敗する場合があります(たとえば、イベントが多すぎる場合や停電の場合)。 これが発生した場合、JFRは、出力ファイルにデータが欠落している可能性があることを通知しようとします。

4. Javaフライトレコーダーの使用方法

JFRは実験的な機能であるため、その使用法は変更される可能性があります。 実際、以前のディストリビューションでは、本番環境で使用するために商用機能をアクティブ化する必要があります。 ただし、JDK 11以降は、何もアクティブ化せずに使用できます。 このツールの使用方法については、Javaの公式リリースノートをいつでも参照できます。

JDK 8の場合、JFRをアクティブ化できるようにするには、オプション +UnlockCommercialFeaturesおよび+FlightRecorderを使用してJVMを起動する必要があります。

上で述べたように、JFRをアクティブ化する方法は2つあります。 アプリケーションの起動と同時にアクティブ化する場合は、コマンドラインからアクティブ化します。 アプリケーションがすでに実行されている場合は、診断コマンドツールを使用します。

4.1. コマンドライン

まず、標準のjavaコンパイラ java c を使用して、プログラムの*。javaファイルを*。classにコンパイルします。

コンパイルが成功したら、次のオプションを使用してプログラムを開始できます。

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder 
  -XX:StartFlightRecording=duration=200s,filename=flight.jfr path-to-class-file

ここで、 path-to-class-file は、アプリケーションのエントリポイント*。classファイルです。

このコマンドは、アプリケーションを起動し、記録をアクティブにします。記録はすぐに開始され、200秒以内に続きます。 収集したデータは出力ファイルflight.jfrに保存されます。 他のオプションについては、次のセクションで詳しく説明します。

4.2. 診断コマンドツール

jcmdツールを使用してイベントの登録を開始することもできます。 例えば:

jcmd 1234 JFR.start duration=100s filename=flight.jfr

JDK 11より前では、この方法でJFRをアクティブ化できるようにするには、ロック解除された商用機能を使用してアプリケーションを起動する必要があります。

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder -cp ./out/ com.baeldung.Main

アプリケーションが実行されると、そのプロセスIDを使用して、次の形式のさまざまなコマンドを実行します。

jcmd <pid|MainClass> <command> [parameters]

診断コマンドの完全なリストは次のとおりです。

  • JFR.start –新しいJFRレコーディングを開始します
  • JFR.check –実行中のJFR記録をチェックします
  • JFR.stop –特定のJFR記録を停止します
  • JFR.dump –JFR記録の内容をファイルにコピーします

各コマンドには一連のパラメーターがあります。 たとえば、JFR.startコマンドには次のパラメーターがあります。

  • name –録音の名前。 後で他のコマンドでこの録音を参照できるようになります
  • delay –記録開始の時間遅延のディメンションパラメータ。デフォルト値は0秒です。
  • duration –記録期間の時間間隔のディメンションパラメータ。 デフォルト値は0で、これは無制限を意味します
  • filename –収集されたデータを含むファイルの名前
  • maxage –収集されたデータの最大経過時間のディメンションパラメーター。 デフォルト値は0で、これは無制限を意味します
  • maxsize –収集されたデータのバッファーの最大サイズ(バイト単位)。 デフォルト値は0です。これは、最大サイズがないことを意味します

このセクションの冒頭で、これらのパラメーターの使用例をすでに見てきました。 パラメータの完全なリストについては、常に JavaFlightRecordedの公式ドキュメントを参照してください。

JFRは、JVMとアプリケーションのパフォーマンスのフットプリントをできるだけ少なくするように設計されていますが、少なくとも1つのパラメーター duration 、を設定して、収集されるデータの最大量を制限することをお勧めします。 maxage 、またはmaxsize

5. 動作中のJavaフライトレコーダー

サンプルプログラムを使用して、JFRの動作をデモンストレーションしましょう。

5.1. サンプルプログラム

このプログラムは、 OutOfMemoryError が発生するまで、オブジェクトをリストに挿入します。 次に、プログラムは1秒間スリープします。

public static void main(String[] args) {
    List<Object> items = new ArrayList<>(1);
    try {
        while (true){
            items.add(new Object());
        }
    } catch (OutOfMemoryError e){
        System.out.println(e.getMessage());
    }
    assert items.size() > 0;
    try {
        Thread.sleep(1000);
    } catch (InterruptedException e) {
        System.out.println(e.getMessage());
    }
}

このコードを実行しないと、潜在的な欠点を見つけることができます。 while ループは、CPUとメモリの使用率が高くなります。 JFRを使用してこれらの欠点を確認し、おそらく他の欠点を見つけましょう。

5.2. 登録を開始します

まず、コマンドラインから次のコマンドを実行してプログラムをコンパイルします。

javac -d out -sourcepath src/main src/main/com/baeldung/flightrecorder/FlightRecorder.java

この時点で、 out / com / baeldung /FlightrecorderディレクトリにファイルFlightRecorder.classが見つかります。

次に、次のオプションを使用してプログラムを開始します。

java -XX:+UnlockCommercialFeatures -XX:+FlightRecorder 
  -XX:StartFlightRecording=duration=200s,filename=flight.jfr 
  -cp ./out/ com.baeldung.flightrecorder.FlightRecorder

5.3. データの視覚化

ここで、ファイルFlight.jfrをJDKディストリビューションの一部であるJavaMissionControlにフィードします。 これは、イベントに関するデータをわかりやすく直感的な方法で視覚化するのに役立ちます。

そのメイン画面には、プログラムが実行中にCPUをどのように使用していたかに関する情報が表示されます。 CPUに大きな負荷がかかっていることがわかります。これは、whileループが原因でかなり予想されます。

ビューの左側には、一般メモリコードスレッドなどのセクションがあります。 各セクションには、詳細情報を含むさまざまなタブが含まれています。 たとえば、セクションコードのタブホットメソッドには、メソッド呼び出しの統計が含まれています。

このタブでは、サンプルプログラムのもう1つの欠点を見つけることができます。メソッド java .util.ArrayList.grow(int)は、配列容量を増やすために17回呼び出されました。オブジェクトを追加するための十分なスペース。

より現実的なプログラムでは、他にも多くの有用な情報が表示される場合があります。

  • ガベージコレクターによって作成および破棄されたときの、作成されたオブジェクトに関する統計
  • スレッドがロックまたはアクティブになったときのスレッドの時系列に関する詳細なレポート
  • アプリケーションが実行していたI/O操作

6. 結論

この記事では、JavaFlightRecorderを使用したJavaアプリケーションの監視とプロファイリングのトピックを紹介しました。 このツールはまだ実験的なものであるため、より完全で最近の情報については、その公式サイトを参照する必要があります。

いつものように、コードスニペットはGithubリポジトリで利用できます。