Flight RecorderによるJavaアプリケーションの監視

1. 概要

このチュートリアルでは、Java Flight Recorder、その概念、基本的なコマンド、およびその使用方法を検証します。

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

Javaは単なるプログラミング言語ではなく、多くのツールを備えた非常に豊かなエコシステムです。 JDKには、独自のプログラムをコンパイルしたり、プログラム実行の全ライフサイクル中にJava仮想マシンの状態や状態を監視したりできるプログラムが含まれています。
JDKディストリビューションの_bin_フォルダーには、特に、プロファイリングと監視に使用できる次のプログラムが含まれています。
  • * Java VisualVM *(jvisualvm.exe)

  • * JConsole *(jconsole.exe)

  • * Java Mission Control *(jmc.exe)

  • 診断コマンドツール(jcmd.exe)

    このフォルダのコンテンツを調べて、使用可能なツールを確認することをお勧めします。
    このチュートリアルでは、Java Flight Recorderに焦点を当てます。 これは、スタンドアロンプ​​ログラムではないため、上記のツールには含まれていません。 その使用法は、上記の2つのツール、Java Mission ControlおよびDiagnostic Command Toolsと密接に関連しています。

3. Java Flight Recorderとその基本概念

Java Flight Recorder(JFR)は、* Javaアプリケーションの実行中にJava仮想マシン(JVM)のイベントに関する情報を収集する監視ツールです*。 JFRはJDKディストリビューションの一部であり、JVMに統合されています。
JFRは、実行中のアプリケーションのパフォーマンスにできるだけ影響を与えないように設計されています*。
JFRを使用するには、アクティブ化する必要があります。 これは次の2つの方法で実現できます。
  1. Javaアプリケーションを起動するとき

  2. Javaアプリケーションの場合、_jcmd_ツールの診断コマンドを渡す
    すでに実行されています

    JFRにはスタンドアロンツールはありません。 Java Mission Control(JMC)を使用します。これには、JFRによって収集されたデータを視覚化できるプラグインが含まれています。
    これら3つのコンポーネント(_JFR _、_ jcmd_、および_JMC_)は、実行中のJavaプログラムの低レベルのランタイム情報を収集するための完全なスイートを形成します。 この情報は、プログラムを最適化するとき、または何か問題が発生したときに診断するときに非常に役立つことがあります。
    コンピューターにさまざまなバージョンのJavaがインストールされている場合、Javaコンパイラー(_javac _)、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 Flight Recorderの使用方法

JFRは実験的な機能であるため、その使用は変更される可能性があります。 実際、以前のディストリビューションでは、実稼働で使用するために商用機能をアクティブにする必要があります。 ただし、JDK 11以降では、何もアクティブ化せずに使用できます。 このツールの使用方法を確認するには、いつでも公式のJavaリリースノートを参照してください。
JDK 8でJFRを有効にするには、オプション_ + UnlockCommercialFeatures_および_ + FlightRecorder_を使用してJVMを起動する必要があります。
前述したように、JFRをアクティブにするには2つの方法があります。 アプリケーションの起動と同時にアクティブ化する場合は、コマンドラインから実行します。 アプリケーションが既に実行されている場合、診断コマンドツールを使用します。

4.1. コマンドライン

最初に、標準のJavaコンパイラ_javac_を使用して、プログラムの_ *。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_ toolを使用して、イベントの登録を開始することもできます。 例えば:
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_コマンドには次のパラメーターがあります。
  • 名前 –録音の名前。これを参照できるようになります
    後で他のコマンドで記録する

  • 遅延 –記録開始の時間遅延の次元パラメータ、
    デフォルト値は0です

  • * duration * –期間の時間間隔の次元パラメーター
    記録の;デフォルト値は0sです。これは無制限を意味します

  • * filename * –収集されたデータを含むファイルの名前

  • * maxage * –収集された最大年齢の次元パラメーター
    データ;デフォルト値は0sです。これは無制限を意味します

  • * maxsize * –バイト単位で収集されたデータのバッファの最大サイズ。その
    デフォルト値は0です。これは、最大サイズがないことを意味します

    このセクションの冒頭で、これらのパラメーターの使用例を見てきました。 パラメータの完全なリストについては、https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/comline.htm#JFRUH190 [Java Flight Recorded official documentation]をいつでも参照できます。
    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. データを視覚化する

ここで、JDKディストリビューションの一部である_flight.jfr_ to * Java Mission Control *ファイルをフィードします。 イベントに関するデータをわかりやすく直感的に視覚化するのに役立ちます。
メイン画面には、実行中にプログラムがCPUをどのように使用していたかに関する情報が表示されます。 CPUに大きな負荷がかかっていることがわかります。これは、while_while_ループが原因で予想されます。
link:/uploads/main-screen-100x70.png%20100w []
ビューの左側には、セクション_General _、_ Memory _、_ Code_、および_Threads_などがあります。 各セクションには、詳細情報を含むさまざまなタブが含まれています。 たとえば、セクション__Code __のタブ_Hot Methods_には、メソッド呼び出しの統計が含まれています。
link:/uploads/code-screen-hot-methods-100x70.png%20100w []
このタブでは、サンプルプログラムの別の欠点を見つけることができます。オブジェクトを追加するための十分なスペースがないたびに配列の容量を拡大するために、メソッド_java.util.ArrayList.grow(int)_が17回呼び出されました。
より現実的なプログラムでは、他の多くの有用な情報が表示される場合があります。
  • 作成および破棄されたオブジェクトに関する統計
    ガベージコレクター

  • ロックされたときのスレッドの年表に関する詳細なレポート
    またはアクティブ

  • アプリケーションが実行していたI / O操作

6. 結論

この記事では、Java Flight Recorderを使用してJavaアプリケーションを監視およびプロファイリングするトピックを紹介しました。 このツールは実験的なツールであるため、https://docs.oracle.com/javacomponents/jmc-5-4/jfr-runtime-guide/toc.htm [公式サイト]で詳細と最新情報を確認する必要があります。
いつものように、コードスニペットはhttps://github.com/eugenp/tutorials/tree/master/core-java-modules/core-java-perf[Githubで]リポジトリから入手できます。