このトピックでは、フライト記録を検査するためのサンプルJFRの取得方法、およびフライト記録を分析するためのJava Mission Controlの様々なタブについて説明します。次の項で説明します。
フライト記録を作成した後、Mission Controlでそれを開くことができます。フライト記録を検査するための簡単な方法:
Mission Controlを開き、「JVMブラウザ」タブを選択する。
Mission Controlを実行しているJVMオプションを選択して短い記録を作成する。
別の方法としては、デモおよびサンプルをダウンロードし、sample\missioncontrol\flightrecordings\
から記録の1つを開くことです。wldf.jfr
記録は、次の項の例に使用されているアプリケーション・サーバーからのサンプル記録です。
フライト記録を開くと、「全般」、「メモリー」、「コード」、「スレッド」、「I/O」、「システム」および「イベント」などのいくつかのメイン・タブが表示されます。プラグインがインストールされている場合は、他のメイン・タブも表示されることがあります。これらのメイン・タブには、それぞれのサブタブがあります。疑問符をクリックして組込みのヘルプのメイン・タブおよびサブタブに関する項を参照してください。
各タブの上部のビューに、範囲ナビゲータがあります。
図2-8の縦棒は、記録内のイベントを表します。棒の高さが高いほど、より多くのイベントがその時点で発生しています。選択された時間の端をドラッグして、記録のズーム・インまたはズーム・アウトができます。範囲ナビゲータをダブルクリックすると、ズーム・アウトして記録全体が表示されます。すべてのサブタブに同じズーム・レベルを適用するには、「選択の同期」チェック・ボックスをクリックします。
詳細は、組込みヘルプの範囲ナビゲータの使用に関する項を参照してください。イベントの名前は、タブの名前どおりです。
「全般」タブには、アプリケーション全般について説明するいくつかのサブタブが含まれています。図2-9に示すように、最初のサブタブは「概要」で、ここには最大ヒープ使用量、合計CPU使用率およびGC一時休止時間などの基本情報が表示されます。
また、CPU使用率の経時的推移、アプリケーションでの使用状況とマシンでの合計を調べます。このタブは、アプリケーションで直接に問題が発生したときに調べるための便利なタブです。たとえば、100%近くまで急上昇しているCPU使用率、低すぎるCPU使用率、またはガベージ・コレクションの一時休止などに注意してください。
注意: ヒープ統計を指定して開始されたプロファイリング記録は、記録の開始時と終了時に、他のコレクションよりも長くかかる可能性がある、2つのOldコレクションを取得します。
また、「JVM情報」サブタブには、JVM情報が表示されます。起動パラメータのサブタブの「システム・プロパティ」には、設定されたすべてのシステム・プロパティが表示され、「記録」には、オンにされたイベントなど、特定の記録に関する情報が表示されます。すべてのタブおよびサブタブについて組込みの詳細を参照するには、疑問符をクリックしてください。
「メモリー」タブには、ガベージ・コレクション、割当てパターンおよびオブジェクト統計に関する情報が含まれています。このタブは、メモリー・リークのデバッグおよびGCのチューニングのために特に役立ちます。
「概要」タブには、メモリー使用量に関する一般情報およびガベージ・コレクションに関する統計情報が表示されます。注意: 「概要」タブのグラフでは、目盛の最大値がマシンで使用可能な物理メモリーです。そのため、Javaヒープは、下部のわずかな部分のみを取る場合があります。
「メモリー」タブの3つのサブタブは次のとおりです。
「ガベージ・コレクション」タブ: 「ガベージ・コレクション」タブには、メモリー使用量の経時的推移およびすべてのガベージ・コレクションに関する情報が表示されます。
図2-10に示すように、ヒープ使用量のスパイク状のパターンはまったく正常です。ほとんどのアプリケーションでは、一時オブジェクトが絶えず割り当てられています。条件が満たされると、ガベージ・コレクション(GC)がトリガーされ、使用されなくなったすべてのオブジェクトが削除されます。したがって、ヒープ使用量は、GCがトリガーされるまで絶え間なく増加した後、急激に減少します。
JavaのほとんどのGCには、何らかの小規模なガベージ・コレクションがあります。Old GCではJavaヒープ全体が対象となり、他のGCではヒープの一部を調べる場合があります。Oldコレクション後のヒープ使用量は、アプリケーションで使用されているメモリーであり、ライブ・セットと呼ばれています。
ヒープ統計を有効にして生成されるフライト記録は、Old GCで開始および終了します。GCの一覧からそのOld GCを選択し、「全般」タブを選択して「GC理由」を参照すると、ヒープ検査によるGCの開始であることがわかります。通常、これらのGCは、他のGCよりも少し時間がかかります。
メモリー・リークに対処するための最適な方法としては、最初と最後のOld GCでの「GC後のヒープ」の値を確認してください。この値が経時的に増加している場合は、メモリー・リークの可能性があります。
「GC回数」タブには、GCの実行にかかった時間とGCのためにアプリケーションが完全に一時休止する時間に関する情報があります。「GC構成」タブには、GCの構成に関する情報があります。これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
「割当て」タブ: 図2-11では、行われたすべてのメモリー割当ての選択を示しています。Javaの小さなオブジェクトは、TLAB (Thread Local Area Buffer)に割り当てられます。TLABは、新しいオブジェクトが割り当てられている小さなメモリー領域です。TLABが一杯になると、スレッドが新しいものを取得します。すべてのメモリー割当てをログすると、オーバーヘッドが生じるので、新しいTLABをトリガーしたすべての割当てがログされます。大きいオブジェクトは、TLAB外に割り当てられ、これらもログされます。
各クラスのメモリー割当てを推定するには、「新しいTLABの割当て」タブ、「割当て」タブの順に選択します。これらの割当ては、新しいTLABをトリガーするために起こるオブジェクトの割当てです。char
型の配列は、新しいTLABを最も多くトリガーします。どれだけのメモリーがchar
型の配列として割り当てられているかは不明です。TLABのサイズは、char
型の配列によって割り当てられるメモリーを推定するのに役立ちます。
図2-11は、最も多くのメモリーを割り当てるchar
型の配列の例です。いずれかのクラスをクリックして、これらの割当てのスタック・トレースを参照してください。記録の例では、すべての割当てプレッシャの44%がchar
型の配列に由来し、27%がStringBuilder.toString
から呼び出されるArray.copyOfRange
に由来することを示しています。通常、StringBuilder.toString
は、Throwable.printStackTrace
およびStackTraceElement.toString
によって呼び出されます。これらのメソッドの呼出しを確認するには、さらに展開します。
注意: アプリケーションによる一時オブジェクトの割当てが多いほど、アプリケーションで必要なガベージ・コレクションが増えます。「割当て」タブは、ほとんどの割当てを見つけてアプリケーションのGCプレッジャを減らすことに役立ちます。「TLAB外の割当て」タブでは、通常、「新しいTLABの割当て」タブよりもメモリー・プレッシャが少ない、大きいメモリー割当てを参照できます。
「オブジェクト統計」タブ: 「オブジェクト統計」タブには、ほとんどのライブ・セットを持つクラスが表示されます。ライブ・セットについて理解するには、「「メモリー」タブ」の「ガベージ・コレクション」サブタブを参照してください。図2-12では、フライト記録のヒープ統計を示しています。データを表示するには、フライト記録のヒープ統計を有効にしてください。下部の「上位の増加」タブでは、フライト記録中に各オブジェクト・タイプのサイズがどれだけ増加したかを示しています。特定のオブジェクト・タイプのサイズが大きく増加した場合にはメモリー・リークを示していますが、わずかな変動は正常です。特に、標準Javaクラス以外の上位の増加を調査します。
「コード」タブには、アプリケーションが時間の大半を費やしている場所の情報が含まれます。「概要」サブタブには、最も多くの実行時間を費やしたパッケージおよびクラスが表示されます。これはサンプリングからのデータです。JFRでは、一定の間隔で実行中のスレッドのサンプルを取ります。実際のコードを実行しているスレッドのみがサンプリングされ、スリープ中、ロックまたはI/Oを待機中のスレッドは表示されません。
実際のコードを実行するためのアプリケーション時間の詳細は、「ホット・メソッド」サブタブを参照してください。
図2-13では、最も多くサンプリングされたメソッドを示しています。これらの呼出し元を確認するには、サンプルを展開します。HashMap.getEntry
の呼出しが多い場合は、最も多く呼び出したメソッドが見つかるまでこのノードを展開します。このタブは、アプリケーションのボトルネックを見つけるのに最適です。
「呼出しツリー」サブタブでは、同じイベントが下から(Thread.run
などから)順に表示されます。
「例外」サブタブには、スローされた例外が表示されます。デフォルトではエラーのみがログされますが、すべての例外を含めるには、新しい記録を開始するときにこの設定を変更します。
「コンパイル」サブタブには、アプリケーションが実行されていたときにコンパイルされたメソッドが表示されます。
「クラスのロード」サブタブには、時間の経過とともにロードされたクラス数、実際にロードされたクラスおよびアンロードされたクラスが表示されます。このサブタブは、記録の開始時にクラス・ロード・イベントが有効であった場合にのみ情報が表示されます。
これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
「スレッド」タブには、スレッド、ロックの競合およびその他の待機時間に関する情報が含まれます。
「概要」サブタブには、CPU使用率およびスレッド数の経時的な推移が示されます。
「ホット・スレッド」サブタブには、ほとんどのコード実行を行うスレッドが表示されます。この情報は、「コード」タブの「ホット・メソッド」サブタブと同じサンプリング・データに基づいています。
「競合」タブは、ロックの競合に起因するボトルネックを見つけるのに役立ちます。
図2-14では、同期のための待機時間が長いオブジェクトを示しています。各オブジェクトの待機時間のスタック・トレースを参照するには、クラスを選択します。通常、これらの一時休止は、別のスレッドがロックを保持している同期メソッドによって生じます。注意: デフォルトでは、10msより長い同期イベントのみが記録されますが、記録の開始時にこのしきい値を下げることができます。
「待機時間」サブタブは、たとえば、スリープまたは待機の呼出し、ソケットからの読取り、ファイルI/Oの待機など、その他の待機時間の原因を示します。
「スレッド・ダンプ」サブタブには、記録内でトリガーできる定期的なスレッド・ダンプが表示されます。
「ロック・インスタンス」サブタブには、同期のために最も待機しているオブジェクトの正確なインスタンスが表示されます。
これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。
「I/O」タブには、ファイルの読取り、ファイルの書込み、ソケットの読取りおよびソケットの書込みに関する情報が表示されます。このタブは、特に、I/O操作に時間がかかる場合など、アプリケーションに応じて役立ちます。注意: デフォルトでは、10msより長いイベントのみが表示されます。しきい値は、新しい記録を作成するときに変更できます。
「システム」タブは、アプリケーションが実行されているマシンのCPU、メモリーおよびOSに関する詳細を提供します。また、環境変数およびJVMと同時に実行されている他のプロセスも表示されます。
「イベント」タブには、記録のすべてのイベントが表示されます。これは様々な方法で使用できる詳細タブです。これらのタブの詳細は、右上の疑問符をクリックして組込みのヘルプを参照してください。