CPU高負荷
アプリケーションの性能が劣化している場合、まず、CPU資源が不足していないかCPU使用率を確認します。
JMCで[アウトライン]タブの[プロセス]を選択します。
以下の例では、システム全体のCPU使用率がほぼ100%になっており、アプリケーションのCPU使用率が60%程度になっています。このことから、アプリケーションのプロセス以外にCPUを多く使っているプロセスがあり、アプリケーションの性能に影響を与えている可能性があることがわかります。
[CPU使用率]のグラフデータの意味は以下のとおりです。
橙色:システム全体のCPU使用率
青色:アプリケーションのユーザーモードでのCPU使用率
灰色:アプリケーションのカーネルモードでのCPU使用率
CPU使用率高騰時のプロセス一覧を調べるためには、““SystemProcess”イベント”を使用します。
[同時プロセス]のグラフから、“SystemProcess”イベントが記録されたときの実行中プロセスについて調べます。以下の例では、同時に255プロセスが実行されていることがわかります。[同時プロセス]のグラフにカーソルを合わせると同時プロセス数が表示され、グラフを選択するとグラフの下に実行中のプロセスの一覧が表示されます。
一覧の中に、CPUを多く使うアプリケーション以外のプロセスがある場合は、アプリケーションの性能に影響がでないように対処してください。
“SystemProcess”イベントは定期的にシステムで実行中のプロセス一覧を記録します。イベントの有効・無効、およびイベントの詳細は、“jdk.SystemProcess”で設定します。
プロセス一覧の採取間隔は“period”プロパティで指定できます。本製品提供のイベント設定ファイルのデフォルトは“endChunk”が設定されており、以下のタイミングで記録されます。
記録の終了時
チャンクファイル切り替え時
<event name="jdk.SystemProcess"> <setting name="enabled">true</setting> <setting name="period">endChunk</setting> </event>
イベント設定ファイルの設定方法は、“イベント設定ファイル”を参照してください。
ポイント
アプリケーションのプロセスの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”イベントは、以下のメソッドを直接、または間接的に実行したときの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”イベントは、“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> <event name="jdk.SocketWrite"> <setting name="enabled">true</setting> <setting name="stackTrace">true</setting> <setting name="threshold" control="socket-io-threshold">20 ms</setting> </event>
イベント設定ファイルの設定方法は、“イベント設定ファイル”を参照してください。
その他の性能低下
上記以外の要因で性能低下がある場合は、メソッドプロファイリングにより、アプリケーションのコストの高い部分を調査するのが有効です。
JMCで[アウトライン]タブの[メソッド・プロファイリング]を選択して、メソッドプロファイリングを表示します。
メソッドプロファイリングでは、定期的にスレッドの状態をサンプリングし、““ExecutionSample”イベント”、および““NativeMethodSample”イベント”に記録されます。ただし、デフォルトで無効化されています。詳細は、各イベントの説明および“注意”を参照してください。
メソッドプロファイリングでは、どのメソッドが実行されているかを定期的に調べてカウントします。
メソッドの実行時間は計測しませんが、定期的にプロファイリングしたときに動作しているメソッドをカウントするので、カウント数が多いということは実行時間が長いことを示します。
以下では、“SamplingThread.method2()”メソッドが199回カウントされ、全体の98%を占めていることがわかります。
[スタック・トレース]の表示では、“run()”メソッド、“methodA()”メソッド、“method1()”メソッド、“method2()”メソッドが199回カウントされていることから、このスタックトレースの順で“method2()”メソッドを実行しているときにサンプリングしたことになります。
この例の場合、“method2()”メソッドのコードの実行時間が長くなる要因がないかを調査して、その要因を排除するように対処します。