アプリのメモリリークを調べようとしていますがMAT
、ここでlist_object
いくつかの数値intShallow heap
とretained heap
columnを見つけました。これらの値は何ですか、そしてメモリリークがどこにあるかを知る方法。
3 に答える
Nikita Salnikov-Tarnovskiのブログから:
浅いヒープは簡単です。オブジェクト自体が占めるヒープのみで構成されます。計算方法には微妙な違いがありますが、この記事の範囲ではそのままにしておきます。同じトピックに関する今後の投稿にご期待ください。
保持されたヒープは、多くの点でより興味深いものです。浅いヒープに関心があることはめったにありません。ほとんどの場合、実際の質問は「このオブジェクトをメモリから削除すると、ガベージコレクタによってどれだけのメモリを解放できるか」に変換できます。
さて、私たち全員が覚えているように、すべてのJavaガベージコレクション(GC)アルゴリズムは次のロジックに従います。
1)GCによって「重要」と見なされるオブジェクトがいくつかあります。これらはGCルートと呼ばれ、(ほとんど)破棄されることはありません。たとえば、現在、メソッドのローカル変数と入力パラメータ、アプリケーションスレッド、ネイティブコードからの参照、および同様の「グローバル」オブジェクトを実行しています。
2)これらのGCルートから参照されるオブジェクトはすべて使用中であると見なされるため、GCによって破棄されません。1つのオブジェクトはJavaでさまざまな方法で別のオブジェクトを参照できます。最も一般的なケースでは、オブジェクトAはオブジェクトBのフィールドに格納されます。このような場合、「BはAを参照します」と言います。
3)GCルートから一時的に到達できるすべてのオブジェクトにアクセスし、「使用中」とマークされるまで、このプロセスが繰り返されます。
4)それ以外はすべて未使用であり、廃棄することができます。
浅いヒープと保持されたヒープ
浅いヒープは、1つのオブジェクトによって消費されるメモリです。オブジェクトには、参照ごとに32ビットまたは64ビット(OSアーキテクチャに応じて)、整数ごとに4バイト、ロングごとに8バイトなどが必要です。ヒープダンプ形式に応じて、サイズを調整できます(たとえば、8に揃えます。 )VMの実際の消費量をより適切にモデル化する。
保持されているXのセットは、XがガベージコレクションされたときにGCによって削除されるオブジェクトのセットです。
Xの保持されたヒープは、保持されたXのセット内のすべてのオブジェクトの浅いサイズの合計です。つまり、Xによって保持されているメモリです。
一般的に、オブジェクトの浅いヒープはヒープ内のサイズであり、同じオブジェクトの保持サイズは、オブジェクトがガベージコレクションされたときに解放されるヒープメモリの量です。
特定のクラスのすべてのオブジェクト、特定のクラスローダーによってロードされたすべてのクラスのすべてのオブジェクト、または単に任意のオブジェクトの束など、主要なオブジェクトセットの保持セットは、次のすべてのオブジェクトの場合に解放されるオブジェクトのセットです。その主要なセットにアクセスできなくなります。保持されるセットには、これらのオブジェクトと、これらのオブジェクトを介してのみアクセス可能な他のすべてのオブジェクトが含まれます。保持されるサイズは、保持されるセットに含まれるすべてのオブジェクトの合計ヒープサイズです。
最小保持サイズは、オブジェクトのセットの正確な保持サイズよりもはるかに速く計算される保持サイズの適切な(過小)推定を提供します。これは、ヒープダンプ内のオブジェクトの数ではなく、検査されたセット内のオブジェクトの数にのみ依存します。
簡単に言うと、オブジェクトの浅いヒープはヒープ内のサイズであり、同じオブジェクトの保持サイズは、オブジェクトがガベージコレクションされたときに解放されるヒープメモリの量です。 詳細