Application Real-Time Monitoring Service (ARMS) アプリケーションモニタリングのすぐに使える継続的プロファイリング機能は、Java プログラムにおける CPU、メモリ、または I/O によって引き起こされるボトルネックを効果的に発見し、開発者がプログラムを最適化し、レイテンシを削減し、スループットを向上させ、コストを削減するのに役立ちます。このトピックでは、継続的プロファイリング機能のフレームグラフを使用してパフォーマンスボトルネックを特定する方法について説明します。
前提条件
継続的プロファイリング機能が有効になっていること。詳細については、継続的プロファイリング機能を使用するを参照してください。
定義
フレームグラフはプログラムのパフォーマンスを視覚化し、消費時間など、プログラムの関数呼び出しに関する情報を表示して、開発者がそれらを追跡できるようにします。
フレームグラフは、x 軸、y 軸、および複数のボックスで構成されます。各ボックスはスタック内の関数を表します。x 軸は関数のリソース使用率の割合を測定し、y 軸は関数の深さを測定します。異なる時点のフレームグラフを比較することで、プログラムのパフォーマンスボトルネックを効率的に診断および処理できます。
カテゴリ
フレームグラフは、フレームグラフ(狭義)とアイシクルグラフの 2 つのカテゴリに分類されます。狭義のフレームグラフでは、図 1 に示すように、最上位の要素が上部に、最下位の要素が下部に配置されます。アイシクルグラフでは、図 2 に示すように、最上位の要素が下部に、最下位の要素が上部に配置されます。
図 1. フレームグラフ(狭義)
図 2. アイシクルグラフ
フレームグラフを使用する
フレームグラフはスタックを表すため、ボックスの幅が広い関数は、ボックスの幅が狭い関数よりも多くの CPU を消費します。
コンピュータサイエンスでは、スタックは、プッシュとポップという 2 つの主要な操作を持つ要素の集合体として機能する抽象データ型です。プッシュ操作はスタックに要素を挿入し、ポップ操作はスタックから要素を削除します。スタックの底部には最初に呼び出された関数が含まれ、スタックの最上部には最近呼び出された子関数が含まれます。最上部で最後の子関数が実行されると、スタックから削除されます。関数の実行に消費される時間が長いほど、その親関数によって消費される時間も長くなり、ボックスの幅も広くなります(次の図を参照)。
フレームグラフを分析するには、次の手順を実行します。
フレームグラフの種類に基づいて最上部を見つけます。
フレームグラフのリソース使用率の合計が高い場合は、スタック最上部に幅の広いボックスがあるかどうかを確認します。
スタック最上部に幅の広いボックスがある場合は、上から下へと検索し、アプリケーションによって定義された最初のメソッドを見つけ、そのメソッドを最適化できるかどうかを確認します。
例
次の図は、リソース使用率が高いフレームグラフを示しています。次の手順を実行して、パフォーマンスボトルネックを発見します。
スタック最上部が下部に、スタック底部が上部にあるアイシクルグラフであるため、下から上へと分析する必要があります。
スタック最上部の右側にある java.util.LinkedList.node(int) メソッドには、幅の広いボックスがあります。
java.util.LinkedList.node(int) メソッドは Java Development Kit (JDK) のライブラリ関数であるため、さらに上に検索する必要があります。java.util.LinkedList.get(int) メソッドとその親メソッドである com.alibaba.cloud.pressure.memory.HotSpotAction.readFile() を見つけることができます。アプリケーションによって定義された最初のサービスメソッドである com.alibaba.cloud.pressure.memory.HotSpotAction.readFile() メソッドは 3.89 秒を消費し、スタックの 76.06% を占めています。したがって、指定された期間に com.alibaba.cloud.pressure.memory.HotSpotAction.readFile() メソッドが大量のリソースを消費するという結論を導き出すことができます。このメソッドを使用して、関連メソッドのロジックを分析し、最適化できるかどうかを確認できます。
さらに、フレームグラフの左下隅にある java.net.SocketInputStream メソッドに基づいて、アプリケーションによって定義された最初の親メソッドが com.alibaba.cloud.pressure.memory.HotSpotAction.invokeAPI であることがわかり、スタックの約 23% を占めています。