JProfiler ヘルプDownload

ガベージコレクタ分析


ガベージコレクタ (GC) のランタイム特性を理解し分析することは、いくつかの理由で重要です。まず第一に、GCの停止はアプリケーションの応答性に直接影響を与える可能性があります。 ガベージコレクタの動作を理解することで、これらの停止を減らすために設定を最適化することができます。 一般的に、頻繁で長いGCサイクルは、ヒープが小さすぎるか、一時オブジェクトが多すぎることを示している可能性があります。

ガベージコレクタプローブを使用することで、これらの問題を解決し、適切なガベージコレクタの選択、ヒープサイズ、その他のJVMパラメータなど、JVM設定を調整する際により情報に基づいた決定を下すことができます。

ガベージコレクタプローブは他のプローブとは異なるビューを持ち、異なるデータソースを使用します。 そのデータはJVMのプロファイリングインターフェースから取得されるのではなく、JFRストリーミングを使用してGC関連のイベントをJDKフライトレコーダーから分析します。 JFRイベントストリーミングに依存しているため、GCプローブはJava 17以上のHotspot JVMでプロファイルされた場合にのみ利用可能です。 JFRスナップショットを開くと、使用されているJavaバージョンに関係なく、同じプローブが利用可能です。

ガベージコレクションビュー

ガベージコレクタプローブのメインビューは「ガベージコレクション」テーブルです。これは、記録されたすべてのガベージコレクションを行として表示し、最も重要なメトリクスを列として表示します。

「原因」列は、なぜガベージコレクションがトリガーされたかを示します。例えば、System.gc()の呼び出しが完全なガベージコレクションをトリガーしました。 それは「コレクタ」列の関連する「G1Full」値からわかります。また、20msの大幅な停止を引き起こしたため、一般的にSystem.gc()を呼び出すことは良い考えではありません。 他の原因は、若い世代スペースのコレクション(「G1New」)や、古い世代の未参照オブジェクトをクリーンアップするG1コレクタの古いGCコレクション(「G1Old」)をトリガーします。 古いGCコレクションは、若い世代のコレクションよりも一貫して長くかかりますが、若い世代のコレクションはより多くのオブジェクトを収集します。

特殊なGC処理を伴う収集された参照は、「final」、「weak」、「soft」、「phantom」参照として別々の列に表示されます。

最長の停止と停止の合計のために別々の列がある理由は、各ガベージコレクションが複数のフェーズで構成され、それぞれが別々の停止を生成するためです。 また、ガベージコレクションの「期間」は停止の合計と等しくありません。ガベージコレクションは実行中にJVMを部分的にしか停止しないためです。 スクリーンショットの「G1Old」コレクションは、期間の約5分の1しか停止しないことがわかります。

ガベージコレクションのさまざまなフェーズを調査するには、「GC ID」列のツリーアイコンを切り替えることができます。

上のスクリーンショットでは、G1コレクタの混合GCコレクション(「G1Old」)が展開されています。ほとんどの時間が「クラスアンロード」に費やされており、これはJVMを停止しません。 右側には、ガベージコレクションのさらなる統計が表示されています。ここでは、使用されたヒープは同じままで、使用されたメタスペースは0.1%増加しました。

各コレクタのフェーズは異なります。上のスクリーンショットでは、完全なコレクションが表示されています。ヒープ全体のライブオブジェクトをマークするのに多くの時間を費やしています。 コレクションの終わりには、使用されたヒープが15.7%減少し、メタスペースは同じままでした。

ガベージコレクションを分析する際には、フィルタリングが異なるガベージコレクションのサブセットを比較するための重要なツールです。 テーブルの上部にはフィルタセレクタがあり、任意の列を選択して対応するフィルタを設定できます。 同様のガベージコレクションを簡単に見る方法は、テーブルのコンテキストメニューを使用して、選択した行の列値に基づいてフィルタ条件を選択することです。

興味のあるガベージコレクションを絞り込むために複数のフィルタを追加できます。アクティブなフィルタはテーブルの上部にラベルとして表示されます。 ネストされたGCフェーズテーブルからフィルタを追加することも可能です。

テレメトリー

GCプローブは「テレメトリー」プローブビューで利用可能な多くのテレメトリーを生成します。

GCの停止を最小限に抑えたい場合は、上部の「最長停止」テレメトリーが最も興味深いものになるでしょう。 テレメトリーの時間軸に沿ってドラッグすると、「ガベージコレクション」ビューで対応するガベージコレクションを選択できます。 垂直方向の解像度を向上させるために、上部のドロップダウンから単一のテレメトリーを選択するか、テレメトリーの名前をクリックすることができます。

上のスクリーンショットでは、時間にわたる停止の合計が表示されています。JProfilerは記録されたデータのヒストグラムを構築することで合計可能な測定を提示します。 ビンの幅は利用可能な水平スペースに依存するため、ヒストグラムのビンはズームレベルに応じて変化し、「スケールに合わせる」が有効な場合はウィンドウの幅に応じて変化します。 変わらないのは、すべてのヒストグラムビンの下の総面積です。

ヒープとメタスペースのテレメトリーは、ガベージコレクションを展開するときに見ることができる統計に基づいています。 これは、完全なプロファイリングセッションのメモリテレメトリーのように定期的にサンプリングされるデータではありません。 ある期間にガベージコレクションが発生しない場合、データはありません。 割り当て活動が少ないJVMでは、時間軸に沿って長い間隔があり、グラフは2つのガベージコレクションの間で補間されるだけです。

これらのテレメトリーのそれぞれには、「GC前」と「GC後」の2つのデータラインがあります。 「使用済みヒープ」テレメトリーでは、通常、違いが大きいです。各時点で、2つのデータラインの値を比較することで、ガベージコレクションがどれだけの作業を行ったかを確認できます。 正確な値を取得するには、ツールチップを見てください。「コミット済みヒープ」テレメトリーとメタスペーステレメトリーでは、両方のラインの違いはしばしば小さいです。

JFRスナップショットを分析している場合、jdk.GCHeapSummary JFRイベントタイプからの同じデータがテレメトリーセクションの「メモリ」テレメトリーでも使用されます。 ただし、その場合、「GC前」と「GC後」の値は同じデータラインに表示され、GCプローブテレメトリーのように1秒ごとの粒度に集約されないため、グラフは異なって見えます。

GCサマリー

GCサマリーは、記録期間全体にわたって集約された測定値を示します。 各測定は、ガベージコレクションの数、平均値、最大値、および合計値を提供します。 最も重要なデータは上部の「停止時間」で、これはアプリケーションの生存性に直接影響を与えます。

他のトップレベルカテゴリは、すべてのコレクションの合計時間を示し、それが若いコレクションと古いコレクションの2つのサブカテゴリに分割されます。

GC設定

ガベージコレクタを調整する際には、明示的に設定されるか、ガベージコレクタ自体によって暗黙的に設定される一般的なプロパティを調査したいかもしれません。

これらのプロパティはすべてのガベージコレクタに共通であり、ガベージコレクタ間の違いを理解するのに役立ちます。

GCフラグ

最後に、GC固有のフラグは、ガベージコレクタのどのプロパティを調整できるかを示し、実際の値を確認することができます。

「起源」列は、フラグがどのように設定されたかを示します。「デフォルト」値は標準設定から変更されていないものであり、「エルゴノミック」フラグはガベージコレクタによって自動的に調整されたものです。 コマンドラインで特定のGCフラグを設定した場合、それらは起源として「コマンドライン」として報告されます。