ページの先頭行へ戻る
Interstage Application Server V13.1.0 チューニングガイド
FUJITSU Software

7.3.1 JFR/JMCの使い方

JFRによるJavaアプリケーションのトラブルシューティングに必要なデータの記録とJMCによるデータ解析の方法について説明します。

JFRの記録開始方法

JFRの記録を開始する方法の一例として、Javaの拡張ランタイム・オプションを使用した方法を説明します。

Javaアプリケーション起動時に以下のオプションを指定してください。なお、パラメータの指定は任意です。

-XX:StartFlightRecording=parameterA=valueA [-XX:FlightRecorderOptions=parameterB=valueB

-XX:StartFlightRecording

JavaアプリケーションのJFR記録を開始するオプションです。

parameterA

JFRで記録を開始するときに、指定できるパラメータの名前です。指定できるパラメータは“-XX:StartFlightRecordingで指定できるパラメータ”を参照してください。

valueA

“parameterA”に指定する値です。指定できる値は“-XX:StartFlightRecordingで指定できるパラメータ”を参照してください。

複数のパラメータを使用する場合は、以下のように指定してください。

-XX:StartFlightRecording=parameter=value,parameter=value

-XX:FlightRecorderOptions

Javaアプリケーション起動時にJFRの挙動を制御するオプションです。“-XX:StartFlightRecording”オプションと同時に指定してください。

parameterB

指定できるパラメータは“-XX:FlightRecorderOptionsで指定できるパラメータ”を参照してください。

valueB

“parameterB”に指定する値です。指定できる値は“-XX:FlightRecorderOptionsで指定できるパラメータ”を参照してください。

複数のパラメータを使用する場合は、以下のように指定してください。

-XX:FlightRecorderOptions=parameter=value,parameter=value


-XX:StartFlightRecordingで指定できるパラメータ

パラメータ

パラメータの説明(注1)

delay=time

Javaアプリケーションの起動から記録を開始するまでの遅延時間を指定します。

  • 省略時:遅延は発生せずアプリケーション起動直後から記録を始めます。

dumponexit={true|false}

Javaプロセスの終了時に、JFRログファイルを生成する指定をします。

  • true:生成する

  • false:生成しない

  • 省略時

    • “filename”パラメータを指定した場合:true

    • “filename”パラメータを指定しない場合:false

duration=time

記録の継続時間を1秒以上の値で指定します。

  • 省略時:アプリケーション終了まで無限に記録します。

filename=path(注2)

JFRログファイルを生成するファイルパスを指定します。“dumponexit=false”と一緒に指定する場合は、“duration”パラメータを指定してください。

  • フルパスでファイル名を指定した場合:指定したファイル名で生成します。

    ファイル名は拡張子“.jfr”で指定し、指定したディレクトリは、あらかじめ作成しておいてください。

  • ディレクトリのパスを指定せずにファイル名だけを指定した場合:Javaプロセスのカレントディレクトリに、指定したファイル名で生成します。

  • ディレクトリのパスだけを指定した場合:“<指定したディレクトリ>/hotspot-pid-<JavaアプリケーションのPID>-id-<JFR記録ID>-<日付情報>.jfr”で生成します。(注3)

    指定したディレクトリは、あらかじめ作成しておいてください。

  • 省略時:“<Javaプロセスのカレントディレクトリ>/hotspot-pid-<JavaアプリケーションのPID>-id-<JFR記録ID>-<日付情報>.jfr”で生成します。(注3)

  • 生成するJFRログファイルと同じ名前のファイルがすでに存在する場合、ファイルは上書きされます。

  • JFRログファイルを生成するディレクトリ、およびJFRログファイルで上書きするファイルには、書き込み権限が必要です。

name=identifier

記録の識別子を指定します。識別子は“jcmd JFR.dump”でJFRログファイルを動的に生成する場合などに指定します。

  • 省略時:JFR記録IDと同じ値が設定されます。(注3)

maxage=time(注4)

チャンクファイルが削除されるまでの期間を指定します。

本パラメータを省略した場合、または、本パラメータ値に0を指定した場合は、アプリケーション終了時までチャンクファイルは削除されません。

チャンクファイルについては、“JFRの記録方法”を参照してください。

maxsize=size(注4)

ディスクバッファに記録可能なデータの最大サイズを指定します。
ただし、以下の場合は特別な動作となります。

  • 0を指定した場合:サイズ制限なく記録されます。

  • 省略時

    • “maxage”パラメータを指定した場合:サイズ制限なく記録されます。

    • “duration”パラメータを指定した場合:サイズ制限なく記録されます。

    • “maxage”パラメータおよび“duration”パラメータを指定しなかった場合:250メガバイトが設定されます。

settings=path

使用するイベント設定ファイル(.jfc)を指定します。

  • 省略時:“<OpenJDKインストールディレクトリ>/jre/lib/jfr/default.jfc”を使用します。

disk={true|false}

ディスクバッファに記録を書き込む指定をします

  • true:ディスクバッファに書き込みます。

  • false:ディスクバッファに書かず、メモリに保持します。

  • 省略時:“true”が設定されます。

注1) 単位として指定する文字

サイズを指定するパラメータに、単位として次の文字を指定します。

  • KB(キロバイト)を指定する場合: “k”または“K”

  • MB(メガバイト)を指定する場合: “m”または“M”

  • GB(ギガバイト)を指定する場合: “g”または“G”

時間を指定するオプションに、単位として次の文字を指定します。

  • 秒を指定する場合: “s”

  • 分を指定する場合: “m”

  • 時を指定する場合: “h”

  • 日を指定する場合: “d”

注2) Interstage Application Server配下でJavaアプリケーションを実行する場合

注意

複数のJavaプロセス起動時に同じjfrファイルを指定した場合、複数のプロセスから同じファイルに対してログを書き込むことになるため、“filename”パラメータにフルパスでファイル名を指定した場合、ログ情報として使えなくなります。

このような場合、“filename”パラメータを省略する、または“path”にディレクトリ名だけを指定してください。

注3) JFR記録ID

JFRの記録単位に自動的に付与するIDのことを示し、JFR記録の識別に使用します。同じJavaプロセスに対して、記録が開始されるごとに、1からカウントアップします。

注4) “maxage”パラメータと“maxsize”パラメータの両方が指定された場合の古いチャンクファイル削除動作について
  • すべてのチャンクファイルの生存期間が“maxage”パラメータ値の期間内、およびディスクバッファの使用量が“maxsize”パラメータ値のサイズ内の場合

    チャンクファイルは削除されません。

  • チャンクファイルの生存期間が“maxage”パラメータ値の期間を過ぎているものが存在する、およびディスクバッファの使用量が“maxsize”パラメータ値のサイズ内の場合

    期間を過ぎたチャンクファイルは、ディスクバッファから削除されます。

  • チャンクファイルの生存期間にかかわらず、ディスクバッファの使用量が“maxsize”パラメータ値を超えた場合

    “maxsize”パラメータ値内になるまで、生存期間の長いチャンクファイルが(たとえそのチャンクファイルが“maxage”パラメータ値の期間内であっても)、ディスクバッファから削除されます。

-XX:FlightRecorderOptionsで指定できるパラメータ

パラメータ

パラメータの説明(注1)

memorysize=size

グローバルバッファのサイズをバイト単位で、1メガバイト以上の値を指定します。

  • 省略時:10mが設定されます。

maxchunksize=size

チャンクファイルの最大サイズをバイト単位で、1メガバイト以上の値を指定します。

  • 省略時:12mが設定されます。

repository=path

記録のディスク書き込み時に使用するディスクバッファのディレクトリを指定します。

  • 省略時:“<システムの一時ディレクトリ>/<yyyy>_<MM>_<dd>_<HH>_<mm>_<ss>_<PID>ディレクトリ”を作成します。

stackdepth=depth

記録するスタックトレースのスタックの深さを、1以上2048以下の値で指定します。

  • 省略時:64が設定されます。

threadbuffersize=size

スレッドローカルバッファのサイズをバイト単位で、4キロバイト以上2ギガバイト以下の値を指定します。

  • 省略時:8kが設定されます。

注1) 単位として指定する文字

サイズを指定するパラメータに、単位として次の文字を指定します。

  • KB(キロバイト)を指定する場合: “k”または“K”

  • MB(メガバイト)を指定する場合: “m”または“M”

  • GB(ギガバイト)を指定する場合: “g”または“G”

指定

Javaアプリケーション起動から30秒後に記録を開始し、5分後に記録が終了します。Javaアプリケーション終了後に“C:¥tmp¥recording.jfr”でJFRログファイルを生成し、“c:\tmp\disk”に一時的に書き込まれます。

-XX:StartFlightRecording=delay=30s,duration=5m,dumponexit=true,filename=C:¥tmp¥recording.jfr -XX:FlightRecorderOptions=repository=c:\tmp\disk

JFR記録方法

JFRが採取するデータの記録場所にはバッファとJFRログファイルがあります。バッファは、アプリケーション実行中にJFRが使用する一時的な記憶領域で、アプリケーション終了時に削除されます。JFRログファイルは、アプリケーション実行中またはアプリケーション終了時にバッファのデータを保存するファイルで、JMCなどのツールにより解析可能なファイルです。

バッファ

バッファには、メモリバッファとディスクバッファの2種類があります。メモリバッファはさらに、スレッドごとのスレッドローカルバッファとスレッド共有のグローバルバッファから構成されています。以下に各特徴について説明します。

バッファの種類

説明

バッファに空きがない場合の処理

書き込み速度

メモリバッファ

スレッドローカルバッファ

Javaスレッドごとにメモリに確保されるバッファ領域。
バッファサイズは“threadbuffersize”パラメータで指定します。

グローバルバッファにフラッシュします。

高速(メモリへの書き込み速度に依存)

グローバルバッファ

Javaプロセスごとにメモリに確保されるバッファ領域。
バッファサイズは“memorysize”パラメータで指定します。

  • “disk”パラメータが“true”の場合:ディスクバッファへフラッシュする。

  • “disk”パラメータが“false”の場合:循環バッファとして機能し、古いデータから順に削除する。

ディスクバッファ

ディスクに一時的に確保されるバッファ領域。
“maxchunksize”パラメータで指定したサイズ以上のデータが書き込まれるごとに、チャンクファイル(*1)が新しく生成されます。最大バッファサイズは“maxsize”パラメータで指定します。

最も古いチャンクファイルを削除する。

低速(ディスクへの書き込み速度、およびデータ量に依存)

*1:JMCで読み込み可能なファイルで、ディスクバッファに生成されます。ファイル名の形式は<yyyy>_<MM>_<dd>_<HH>_<mm>_<ss>.jfrです。


JFRのデータの流れ

  • フラッシュ(*1):スレッドローカルバッファのJFR記録データが、スレッドローカルバッファのサイズを超えたときに、JFR記録データをグローバルバッファにフラッシュします。

  • フラッシュ(*2):グローバルバッファのJFR記録データが、グローバルバッファのサイズを超えたときに、“disk”パラメータが“true”の場合、JFR記録データをディスクバッファにフラッシュします。
    “disk”パラメータが“false”の場合、最も古いJFR記録データを削除します。

  • ダンプ(*3):Javaプロセス終了時、または“jcmd”コマンドで“JFR.dump”実行時、JFRログファイルへダンプします。

  • 破棄(*4):ディスクバッファへのフラッシュ時に、チャンクファイルの合計サイズが、ディスクバッファのサイズを超えたときに、最も古いチャンクファイルが削除されます。

注意

循環バッファの最新のデータだけだと調査ができなくなる場合があります。

グローバルバッファは循環バッファのため、最新のデータは利用可能ですが、メモリ内で確保されるためそのサイズは大きくできません。書き込み速度は遅いですが、長期間のデータを記録するには、“disk”パラメータを“true”にし、ディスクへの書きこみを有効にしてください。

ディスクバッファの見積り

ディスバッファに記録されるイベント量が多くなると、古いデータが削除される場合があります。そのため、アプリケーション実行時に発生が予想されるイベント量やサイズを想定し、ディスクバッファサイズを見積り、“-XX:FlightRecorderOptions”の“maxsize”パラメータに適切な値を設定することを推奨します。

見積りについては、“7.3.8 ディスクバッファの見積り”を参照してください。

JFRログファイル

メモリバッファとディスクバッファ両方に書き込まれたJFR記録データを、JFRログファイル(.jfr)にダンプすることができます。トラブルシューティング時の解析では、このJFRログファイルを使用します。JFRログファイルの解析方法については“JMCの使い方”を参照してください。

JFRログファイルにJFR記録データをダンプする方法は、JFRのパラメータ設定でJavaプロセス終了時に自動的にダンプさせる方法と、Javaツールの“jcmd”コマンドを使用する方法があります。

JFRのパラメータ設定でJFRログファイルにダンプする場合は、“JFRの記録開始方法”を参照してください。

“dumponexit=true”を指定すると、Javaプロセス終了時にJFRログファイルを生成します。

JFRログファイルのパスは“filename”パラメータで指定します。指定しない場合は、javaアプリケーションのカレントディレクトリに“hotspot-pid-<JavaアプリケーションのPID>-id-<JFR記録ID>-<日付情報>.jfr”という名前で生成します。

“jcmd”コマンドを使用する場合は、以下を実行してください。

<OpenJDKインストールパス>/bin/jcmd <JavaアプリケーションのPID> JFR.dump name=<JFRの識別子> filename=<JFRログファイルの生成先>

イベント設定ファイル

JavaプロセスおよびJavaアプリケーションで発生する様々な事象や統計情報(例えば、スレッドダンプやCPU負荷情報など)をイベントと呼び、JFRは各イベントに関するデータを記録します。イベント種別ごとに、記録の有無指定や採取情報の詳細な指定をすることができます。

イベント設定ファイルは、各設定を一括で記載するファイルです。本節で説明しているトラブルシューティングに必要なイベントの具体的な設定方法は、各項を参照してください。


イベント設定ファイルで、各イベント種別の設定は以下のXML構文で記述されています。

<event name="イベント名">
  <setting name="プロパティ名">プロパティの値</setting>
  <setting name="プロパティ名">プロパティの値</setting>
</event>

ThreadAllocationStatistics”イベントの記述例

“enabled”プロパティには“true”、“period”プロパティには“everychunk”が設定されています。

<event name="jdk.ThreadAllocationStatistics">
  <setting name="enabled">true</setting>
  <setting name="period">everyChunk</setting>
</event>

注意

イベントの設定について

設定を変更する場合は、プロパティの値だけを修正してください。

イベント設定ファイルは、JFR起動時に“settings”パラメータに指定します。指定方法については、“JFRの記録開始方法”を参照してください。

イベント設定ファイルの特徴

本製品では、以下の3つのイベント設定ファイルが使用でき、“<OpenJDKインストールパス>/jre/lib/jfr”に存在します。

また、イベント設定ファイルをカスタマイズして使用することもできます。

提供している3つの各イベント設定ファイルの特徴について説明します。

  • default.jfc

    “settings”パラメータにイベント設定ファイルを指定しない場合は、このイベント設定ファイルを使用します。

  • profile.jfc

    “default.jfc”より詳細なデータを記録できます。ただし、データを採取するコストは大きくなります。

  • extend.jfc

    本製品で提供するOpenJDKが実装している拡張機能を使用します。拡張機能については“7.2.1 実行中のJavaアプリケーションからトラブルシューティングに必要なデータを記録する機能” を参照してください。

    “extend.jfc”は、“default.jfc”と同じイベントの設定と、拡張機能のイベントの設定を以下のように定義しています。

    ~ 略 ~
    
        <event name="com.fujitsu.jdk.SpecifiedJavaThrowableThrow">
          <setting name="enabled" control="enable-exceptions">false</setting>
          <setting name="stackTrace">true</setting>
          <setting name="className">java.lang.Throwable</setting>
        </event>
    
        <event name="com.fujitsu.jdk.ClassLoadTrace">
          <setting name="enabled" control="class-loading-enabled">true</setting>
          <setting name="stackTrace">false</setting>
          <setting name="threshold">0 ms</setting>
        </event>
    
        <event name="com.fujitsu.jdk.HighCPULoad">
          <setting name="enabled">true</setting>
          <setting name="threshold">10 m</setting>
          <setting name="ratioThreshold">90 %</setting>
        </event>
    
        <event name="com.fujitsu.jdk.HighThreadCPULoad">
          <setting name="enabled">true</setting>
          <setting name="threshold">10 m</setting>
          <setting name="ratioThreshold">90 %</setting>
        </event>
    
    ~ 略 ~
イベント設定ファイルのカスタマイズ

“default.jfc”、“profile.jfc”および“extend.jfc”を直接編集しないでください。

本製品提供のイベント設定ファイルの定義内容と異なる設定をする場合は、対象のイベント設定ファイルをコピーし、ファイル内の変更したいイベントの箇所をカスタマイズしてください。

ロードされたクラスの統計情報を記録する“ClassLoadingStatisticsイベント設定

デフォルトで有効になっており、1000ミリ秒に1回データを記録する設定になっています。

このイベントの場合、“enabled”プロパティの値を“false”に指定することでイベントを無効にして、データを記録しないように設定します。また、“period”プロパティの値を修正すると、定期的にデータを記録する間隔を変更できます。

<event name="jdk.ClassLoadingStatistics">
  <setting name="enabled">true</setting>
  <setting name="period">1000 ms</setting>
</event>

注意

イベント設定ファイルの文字エンコーディングについて

イベント設定ファイルの文字エンコーディングは、UTF-8から変更しないでください。

JFRの性能への影響

JFRは低負荷で実行中のJavaアプリケーションを監視できますが、アプリケーションやJFR起動時の設定パラメータによってオーバーヘッドが大きくなる場合があります。アプリケーションの運用に使用する場合は、スループットやレスポンスなど、性能への影響を検証した上で利用してください。

JFRのオーバーヘッドは、以下のJDKドキュメンテーションを参照してください。

https://docs.oracle.com/javase/jp/8/docs/technotes/guides/troubleshoot/performissues001.html

また、“イベント設定ファイル”の以下のプロパティを変更することで、より詳細なデータを採取することができますが、オーバーヘッドが増加する場合があります。

  • enabled

    “ture”を指定するとイベントが記録されます。“false”から“true”に変更した場合、記録するイベント数が増加します。

  • stackTrace

    “true”を指定するとイベント発生時のスタックトレースが記録されます。頻繁なスタックトレースの出力は、オーバーヘッドが増加します。

  • period

    定期的に記録されるイベントの記録間隔を指定します。
    “period”プロパティに短い間隔を指定すると、記録するイベント数が増加します。

  • threshold

    イベント記録する処理の実行時間が、“threshold”プロパティで指定した時間以上かかった場合にイベントが記録されます。
    “threshold”プロパティを小さくすると、記録するイベント数が増加します。

JMCの使い方

本マニュアルでは、JFRの記録データをダンプしたJFRログファイルを解析する方法を、JMCを例に説明します。

JMCの入手方法

JMCを使用するためには、解析を行う環境にJMCをインストールします。

以下のページより、使用する環境に合わせたAdoptium JMCのバイナリファイルをダウンロードして展開してください。

https://adoptium.net/jmc/

JMC 8.1以降のバージョンでは、JMCを起動するためにJDK11が必要です。

以下のページより、使用する環境に合わせたAdoptium OpenJDK 11のバイナリファイルをダウンロードして展開してください。

https://adoptium.net/temurin/releases/?version=11

注意

Adoptium JMCおよびAdoptium OpenJDKは本製品に含まれない外部ツールです。

OSSおよび外部ツールの利用については、適用された使用条件(ライセンス条件)に従い、お客様の責任において入手、ご利用ください。また、サポートについては、対象外となります。

JMCの説明について

本節では、Windows 10の環境でJMC 8.2.0を使用する前提で説明しています。

注意

説明内で表示している画像は、実際の画面と異なる場合があります。(例えば、情報の表示順序などが異なる場合があります。)

JMCの起動方法

JMCは以下の手順で起動します。起動するとJMCの画面が表示されます。

  1. “<OpenJDK11のインストールパス>/bin”を環境変数PATHの先頭に追加します。

  2. システム一時ディレクトリの“hsperfdata_<ユーザ名>”ディレクトリが書き込み可能な状態であることを確認します。

  3. “<JMCのインストールパス>/JDK Mission Control/jmc.exe”を実行します。

JMCを使う

JMCでJFRログファイルを解析するときは、JMCを起動後、[ファイル]メニューの[ファイルを開く]から解析したいjfrファイルを指定してください。

JMCにはJFRログファイルを自動で分析し、トラブルの原因になりそうな要因を表示する機能があります。

JMCの自動分析の結果は、[アウトライン]タブの[自動分析の結果]を開いて確認してください。

より詳細な情報を確認するためには、[アウトライン]タブの各機能の項目を開いてください。主な機能の説明については“JMCの[アウトライン]タブで確認できる機能”を参照してください。

イベントの詳細情報を確認する場合は、[イベント・ブラウザ]を開いて確認したいイベントを選択してください。なお、JFRのパラメータやイベント設定ファイルの設定によっては、確認できない機能があります。

具体的なトラブルの調査方法については、次項以降を参照してください。

以下では、GCによるアプリケーションの停止などが警告として表示されており、[メモリー]からJavaヒープ使用状況を確認し、ヒープサイズをチューニングするといった対処が考えられます。


JMCの[アウトライン]タブで確認できる機能

機能

各機能で確認できる内容

スレッド

各スレッドのアクティブ時間など

メモリー

Javaヒープ使用状況やクラスごとの使用率

ロック・インスタンス

モニターによってロックされたオブジェクト

ファイルI/O

ファイルI/Oが発生したクラスやI/Oにかかった時間

ソケットI/O

ソケット通信が発生した通信先と通信回数・時間など

メソッド・プロファイリング

JFRの定期的なサンプリングで頻出しているメソッドの統計情報

例外

Javaアプリケーションで発生した例外についての情報

スレッド・ダンプ

定期的に記録されるスレッドダンプ

ガベージ・コレクション

発生したGCの種類やかかった時間

GC構成

GCに関する設定状況

GCサマリ

発生したGCの統計情報

コンパイル

JITコンパイラでコンパイルされた対象メソッドやかかった時間

クラスのロード

ロードされたクラスの統計情報

VM操作

SystemGCなどVMオペレーションの動作状況

TLAB割り当て

TLAB (Thread Local Area Buffer)の割り当て状況

プロセス

Javaプロセスやそれ以外のプロセスのCPU使用率、他のプロセスについての情報

環境変数

Javaアプリケーションを起動した際の環境変数

システム・プロパティ

システムプロパティの値

ネイティブ・ライブラリ

Javaプロセスがロードしたネイティブライブラリ

記録

記録期間などJFRの記録についての情報