アプリケーションのCPU使用率が高騰した場合など、動作が遅延した原因について、JFR/JMCを使って調査する方法を説明します。
CPU高負荷
アプリケーションの性能が劣化している場合、まず、CPU資源が不足していないかCPU使用率を確認します。
-
JMCで[アウトライン]タブの[プロセス]を選択します。
以下の例では、システム全体のCPU使用率がほぼ100%になっており、アプリケーションのCPU使用率が60%程度になっています。このことから、アプリケーションのプロセス以外にCPUを多く使っているプロセスがあり、アプリケーションの性能に影響を与えている可能性があることがわかります。
[CPU使用率]のグラフデータの意味は以下のとおりです。
-
CPU使用率高騰時のプロセス一覧を調べるためには、“
“SystemProcess”イベント
”を使用します。
[同時プロセス]のグラフから、“SystemProcess”イベントが記録されたときの実行中プロセスについて調べます。以下の例では、同時に255プロセスが実行されていることがわかります。[同時プロセス]のグラフにカーソルを合わせると同時プロセス数が表示され、グラフを選択するとグラフの下に実行中のプロセスの一覧が表示されます。
一覧の中に、CPUを多く使うアプリケーション以外のプロセスがある場合は、アプリケーションの性能に影響がでないように対処してください。
-
“SystemProcess”イベント
-
“SystemProcess”イベントは定期的にシステムで実行中のプロセス一覧を記録します。イベントの有効・無効、およびイベントの詳細は、“jdk.SystemProcess”で設定します。
プロセス一覧の採取間隔は“period”プロパティで指定できます。本製品提供のイベント設定ファイルのデフォルトは“endChunk”が設定されており、以下のタイミングで記録されます。
イベント設定ファイルの設定方法は、“
イベント設定ファイル
”を参照してください。
ポイント
アプリケーションのプロセスの
CPU使用率が高騰している場合
“CPULoad”イベントおよび“ThreadCPULoad”イベントで、プロセスおよびスレッドのCPU使用状況を調べることができます。
CPU使用率があらかじめ設定したしきい値を超えた場合の調査は、本製品で提供する拡張機能を使用します。拡張機能については、“
7.3.7 Javaプロセス・JavaスレッドのCPU使用率が高騰している場合
”を参照してください。
ファイルI/O負荷
ファイルI/Oの速度低下によって、性能問題を起こす場合があります。
ファイルI/O発生時のスタックトレースを調査するためには、“
“FileRead”イベントおよび“FileWrite”イベント
”を使用します。
-
JMCで[アウトライン]タブの[ファイルI/O]を選択し、ファイルI/Oの問題を調査します。
[タイムライン]タグを選択すると、ファイルI/OのAPIごとに読込み・書込みのバイト数が表示されます。
[パス][合計I/O時間]等の項目が表示されている箇所に、ファイルのパスごとに、合計I/O時間、I/O回数およびI/Oサイズが表示されます。
時間あたりのI/O回数が多い、または時間あたりのI/Oサイズが小さい場合は、ファイルI/Oが原因で性能問題が起きている可能性があります。
[パス]列に表示されているパス名を選択すると、スタックトレースの統計情報が表示されます。これは、各メソッドがスタックトレースに含まれる割合を示しています。
標準入出力ストリームおよび標準エラーストリームなど、ファイル名を指定しないストリームに対してread/writeのイベントが発生した場合、パス名は、“null”と表示されます。
この例では、ファイルI/O全体の49.3%が“main”メソッド内で費やされたことが分かります。
ファイルのパスや使用されているメソッドの情報をもとに、ファイルI/Oの処理に時間を要しているアプリケーションのコードを確認してください。
-
イベントごとの詳細なログやスタックトレースを調査します。
-
[アウトライン]タブの[イベント・ブラウザ]を選択します。
-
表示された[イベント・ブラウザ]の[イベント・タイプ・ツリー]から、[File Read]または[File Write]を選択します。
各イベントを選択すると、対象となるファイル操作のスタックトレースが[スタック・トレース]に表示されます。
-
“FileRead”イベントおよび“FileWrite”イベント
-
“FileRead”イベントおよび“FileWrite”イベントは、以下のメソッドを直接、または間接的に実行したときのI/O時間が、しきい値を超えた場合だけ記録されます。
-
java.io.FileInputStreamクラスのread()
-
java.io.FileOutputStreamクラスのwrite()
-
java.nio.channels.FileChannelクラスのread()
-
java.nio.channels.FileChannelクラスのwrite()
I/O時間のしきい値は、イベント設定ファイルの“threshold”プロパティで指定します。
イベント設定ファイルのデフォルトの設定では、しきい値は20ミリ秒が設定されています。
<event name="jdk.FileRead">
<setting name="enabled">true</setting>
<setting name="stackTrace">true</setting>
<setting name="threshold" control="file-io-threshold">20 ms</setting>
</event>
<event name="jdk.FileWrite">
<setting name="enabled">true</setting>
<setting name="stackTrace">true</setting>
<setting name="threshold" control="file-io-threshold">20 ms</setting>
</event>
イベント設定ファイルの設定方法は、“
イベント設定ファイル
”を参照してください。
ソケットI/O負荷
ソケットI/Oの速度低下によって、性能問題を起こす場合があります。
ソケットI/O発生時のスタックトレースを、“
“SocketRead”イベントおよび“SocketWrite”イベント
”で調べます。
-
JMCで[アウトライン]タブの[ソケットI/O]を選択し、ソケットI/Oの問題を調査します。
[タイムライン]タブを選択すると、ソケットI/OのAPIごとに読込み・書込みのバイト数が表示されます。
画面上部には、リモートアドレスとリモートポートごとに、合計I/O時間、I/O回数およびI/Oサイズが表示されます。時間あたりのI/O回数が多い、または時間あたりのI/Oサイズが小さい場合は、ネットワーク通信の速度低下が原因で性能問題が起きている可能性があります。
[リモート・アドレス]列のアドレス、または、[リモート・ポート]列のポートを選択すると、スタックトレースの統計情報が表示されます。これは、各メソッドがスタックトレースに含まれる割合を表しています。
この例では、ソケットI/O全体の67.9%が“HttpURLConnection.getResponseCode()”メソッド内で費やされたことが分かります。
リモートアドレスや使用されているメソッドの情報をもとに、ソケットI/Oの処理に時間を要しているアプリケーションのコードを確認してください。
-
イベントごとの詳細なログやスタックトレースを調査します。
-
[アウトライン]タブの[イベント・ブラウザ]を選択します。
-
表示された[イベント・ブラウザ]の[イベント・タイプ・ツリー]から、[Socket Read]または[Socket Write]を選択します。
-
各イベントを選択すると、対象となる通信のスタックトレースが[スタック・トレース]に表示されます。
-
“SocketRead”イベントおよび“SocketWrite”イベント
-
“SocketRead”イベントおよび“SocketWrite”イベントは、“java.net.Socket”が使用する以下のメソッドを直接あるいは間接的に実行したときの I/O時間が、しきい値を超えた場合だけ記録されます。
-
java.io.InputStreamクラスのread()
-
java.io.OutputStreamクラスのwrite()
-
java.nio.channels.SocketChannelクラスのread()
-
java.nio.channels.SocketChannelクラスのwrite()
I/O時間のしきい値は、イベント設定ファイルの“threshold”プロパティで指定します。
イベント設定ファイルのデフォルトの設定では、しきい値は20ミリ秒が設定されています。
<event name="jdk.SocketRead">
<setting name="enabled">true</setting>
<setting name="stackTrace">true</setting>
<setting name="threshold" control="socket-io-threshold">20 ms</setting>
</event>