インタビューの質問:ガベージコレクションメカニズム(GC)

1.ガベージコレクションオブジェクト


JVMランタイムのデータ領域には次のものが含まれます 程序计数器、栈、堆、方法区、本地方法栈

その中で、プログラムカウンター、スタック、ローカルメソッドスタックはスレッドにバインドされており、スレッドが作成されるとメモリに適用され、スレッドが終了すると閉じたいメモリが破棄されます。メソッド領域は主にクラスオブジェクトです。クラスがロードされると、ここでメモリに適用されます。実際、「クラスのアンロード」操作が含まれることはめったにありません。

したがって、垃圾回收机制主要回收的对象就是堆ガベージコレクションは、メモリのアプリケーションがオブジェクト単位で適用されるため、実際にはオブジェクト単位で解放されるメモリを解放します。オブジェクト全体のメモリが使用されていない場合は、没有引用指向这个对象すぐ。リリース

第二に、ガベージコレクションの基本的なプロセス

2.1オブジェクトをリサイクルできるかどうかを判断する(ゴミであるかどうか)

オブジェクトをリサイクルできるかどうかを判断するための基本的な基準は、オブジェクトへの参照がなく、オブジェクトにアクセスする方法がないことです。

方法1、参照カウントアルゴリズム

このメソッドはJAVAでは採用されていませんが、PythonやPHPなどのプログラミング言語のガベージコレクションメカニズムはこのメソッドに役立ちます

使用原理:

すべてのオブジェクトインスタンスには引用计数器

オブジェクトを指す参照が作成されるたびに、カウンターは1ずつインクリメントされ、参照がオブジェクトを指さなくなるたびに、カウンターは1ずつデクリメントされます。

参照カウントがゼロの場合、オブジェクトはガベージコレクションされます

Demo t1 = new Demo();
Demo t2 = t1;

t1 = null;
t2 = null;

ここに画像の説明を挿入

アドバンテージ:

実行効率が高く、プログラムへの影響が少なく、使い方も簡単です。

欠点:

  1. スペース使用率は比較的低いです。参照カウントの方法を使用すると、参照カウントを保存するためにメモリ内に余分なスペースが必要になります。オブジェクト自体が比較的小さく、占有するスペースが少ない場合、現時点でのスペース使用率は非常に低くなります。
  2. 検出循环引用できない状態、メモリリークにつながる
class Demo {
    
    
    Demo t = null;
}

Demo t1 = new Demo();
Demo t2 = new Demo();

t1.t = t2;
t2.t = t1;

t1 = null;
t2 = null;

ここに画像の説明を挿入

t1 = null; t2 = null;を実行すると、参照カウンターが0でなくても、最初のオブジェクトを取得する場合は、最初に2番目のオブジェクトを取得する必要がありますが、2番目のオブジェクトの参照を取得する必要があります。最初のオブジェクトでは、デッドロックされている最初のオブジェクトを最初に取得する必要があります。外の世界では、これら2つのオブジェクトを取得する方法はありません。これらの2つのオブジェクトはガベージと見なす必要がありますが、参照カウントがゼロではないため、ごみリサイクルメカニズムは、必ずしもこれら2つのオブジェクトをごみとは見なしません

方法2.到達可能性分析アルゴリズム

このソリューションは、Javaが採用したソリューションです。

いわゆる、(アクセシビリティ分析の開始点)をレイヤーごと可达に見下ろすことです。逆に、到達不能とは、参照操作がどのように実行されても、オブジェクトにアクセスする方法がないことを意味します。GC Roots通过一系列的引用操作来成功访问到对应的对象

バイナリツリーと同様に、ルートノードからの参照によっていつでもノードにアクセスできますが、バイナリツリーの参照がnullに設定されていると、ノードにアクセスできなくなり、到達できなくなる可能性があります。

ここに画像の説明を挿入

到達可能性分析アルゴリズムは、オブジェクトの参照チェーンが到達可能かどうかを判断することによってオブジェクトをリサイクルできるかどうかを判断することです把所有能够被访问到的对象都标记成“可达”。その後、残りの到達不能オブジェクトはガベージであり、JVMは未标记可达的对象统统释放

アドバンテージ:

  1. 高いスペース使用率

  2. アプリケーションのループによるメモリリークは発生しません

欠点:

各サイクルは多数のオブジェクトをトラバースする必要があります。コード内の参照関係が複雑な場合、トラバース操作にはコストがかかります。

2.2ガベージコレクションアルゴリズム

方法1、マークの削除

ゴミの除去は、最初にリサイクルが必要なゴミオブジェクトをマークし、次にそれらを直接解放します。メモリは解放されますが、多くの欠点があります。

欠点:

  1. 效率比较低下、オブジェクトのマーキングとクリアの2つのプロセスの効率は比較的低いです
  2. マークがクリアされた後产生大量的不连续的内存碎片、ヒープ上に大きなメモリスペースを適用したい大きなオブジェクトインスタンスがある場合、連続したメモリスペースが必要になります。メモリの断片化が発生すると、十分なスペースを見つけることができなくなり、別のゴミをトリガーします。

ここに画像の説明を挿入

方法2.レプリケーションアルゴリズム

使用原理:

  1. メモリを容量に応じて2つの同じサイズのブロックに分割し、一度に1つだけ使用します
  2. 使用中のメモリスペースをガベージコレクションする必要がある場合、残っているオブジェクトはメモリスペースの残りの半分にコピーされます
  3. 以前使用していた古いメモリスペースには、完全にリサイクルできるゴミオブジェクトしか残っていませんが、現時点では、新しいメモリスペースは継続しています。

アドバンテージ:

断片化の問題を修正する

欠点:

  1. メモリ使用量が少なく、一度に使用されているスペースは半分だけです。
  2. 使用しているスペースに残存オブジェクトが多い場合、解放する必要のあるガベージオブジェクトが少なくなり、残存オブジェクトをコピーするための運用コストが比較的高くなります。

方法3:マーキングと仕上げ

使用原理:

  1. 最初にマークする
  2. 残っているすべてのオブジェクトをそれらの1つに移動してから、境界の外側にメモリを破棄します

ここに画像の説明を挿入

アドバンテージ:

  1. スペースの断片化の問題はありません
  2. 存続するオブジェクトが多数ある場合は、レプリケーションアルゴリズムによって引き起こされるレプリケーション効率の問題を回避してください

方法4.世代別リサイクル

上記のリサイクル方法はさまざまなシナリオに適用できます。実際、JVMは上記のアルゴリズムを組み合わせて、全体的なガベージコレクションの問題を解決します。

世代別コレクションは、オブジェクトの年齢に応じて分割されます。いわゆる年齢とは、GCの数を指します。GCの到達可能性分析は定期的であり、経験するサイクルが多いほど、オブジェクトは古くなります

Javaヒープはに分割され新生代和老年代、新世代には次のものが含まれます。伊甸区(Eden)和两块生存区

ここに画像の説明を挿入

使用原理:

  1. 新创建出的对象诞生在伊甸区、新しいオブジェクトのライフサイクルはほとんどが比較的短く、各ガベージコレクションで多数のオブジェクトが停止し、存続するのはごくわずかであるため、复制算法
  2. Edenブロック内のオブジェクトがGCの最初のラウンドを生き残った場合、そのオブジェクトはブロックの生存区1つに入ります。同じ長さの2つのリビングエリアがあり、それらも复制算法オブジェクトを解放することによって解放されます。
  3. オブジェクトが2つのリビングエリア間で前後に存続する場合若干轮 GC、あなたはそうすることができ升级为老年代、オブジェクトは古い世代にコピーされます
  4. 老年期に入るオブジェクトも定期的にGCスクリーニングを受ける必要があります。スキャンの頻度は以前よりも低くなります。老年期のオブジェクトの生存率は高く、それを割り当てるための余分なスペースはあり标记整理ません。アルゴリズムを使用して、メモリを解放します。

インタビューの質問:マイナーGC、メジャーGC、フルGCの違いは何ですか

(1)マイナーGC

つまり新生代GC、若い世代で発生するガベージコレクションを指します。若い世代のスペースが不足すると、マイナーGCがトリガーされます(ここでは、エデンエリアのスペースの不足を指します)。これは、ほとんどのJavaオブジェクトが死ぬという特性を持っているため、マイナーGCが非常に頻繁に発生し、回復速度は一般的に速いです。アルゴリズム

(2)メジャーGC

つまり老年代GC、旧世代で発生するガベージコレクションを指します。古い世代でスペースが不足している場合は、最初にマイナーGCをトリガーしようとします。それでもスペースが不足している場合は、メジャーGCがトリガーされます。多くの場合、少なくとも1つのマイナーGCが伴います(絶対ではありませんが、Parallel Scavengeコレクターには、メジャーGCを直接実行するための戦略選択プロセスがあります)。メジャーGCは、通常、マイナーGCよりも10倍以上低速です。タグ付けアルゴリズム

(3)フルGC

に対して新生代、老年代的GC

ミニオールGCのワークロードが比較的小さいというだけで、オーバーヘッドも小さく、プログラムへの影響もほとんどありません。
一般的に、メジャーGCはフルGCとして概算できます。

3.ガベージコレクター

ガベージコレクターは、ガベージコレクションアルゴリズム用のJVMの特定の実装です。

(1)シリアルコレクター(新世代コレクター)

シリアル

このコレクターは单线程串行コレクターであり、ガベージコレクション作業を完了するために1つのコレクションスレッドのみを使用します。ガベージコレクションが行われると、コレクションが終了するまで他のすべてのワーカースレッドを一時停止する必要があります(Stop The World、stop The allプログラム、STWと呼ばれる)

ここに画像の説明を挿入

SafePoint

Safepointは、コード実行プロセスの特別な位置と考えることができます。スレッドがこれらの位置まで実行されると、スレッドはすべてのユーザースレッドを一時停止します。

SafePointは、他のスレッドが読み取るために他の場所で利用できない現在のスレッドの実行情報を保存して、このスレッドで使用されているメモリと使用されていないメモリを認識します。スレッドがSafePointの位置にある場合にのみ、未使用のメモリの特定の部分を再利用するなど、JVMのスタック情報が変更されると、スレッドはそれを認識して実行を継続します。

したがって、GCは、すべてのスレッドが同時にSafePointに入り、そこに留まり、GCがメモリを処理するのを待ってから、すべてのスレッドが実行を継続することを要求する必要があります。すべてのスレッドがSafePointに入って待機するこの状況のように、世界を止めろ

(2)ParNewコレクター(新世代コレクター)

このコレクターは単一の多线程并行コレクターであり、残りの機能はシリアルコレクターと同様です

ここに画像の説明を挿入

(3)パラレルスカベンジコレクター(新世代コレクター)

パラレル[ˈpærəlel]スカベンジ[ˈskavɪn(d)ʒ]

コレクターは新世代のコレクターであり、複製アルゴリズムを使用するコレクターでもあり、并行的多线程コレクターでもあります。相当于ParNew 收集器的升级版

(4)シリアル旧コレクター(旧世代コレクター)

と同等Serial 收集器的老年代版本です。アルゴリズム单线程串行を使用したコレクターでもあります标记整理

(5)Parallel Old Collector(旧世代コレクター)

同等であり、アルゴリズムを使用してコレクターでParallel Scavenge收集器的老年代版本もあります多线程串行标记整理

(6)CMSコレクター(旧世代コレクター)

このコレクターの目的は尽可能的减小 STW 带来的影响、ガベージコレクションステージのごく一部のみがSTWをトリガーすることです大部分的操作是可以和用户线程并发

ここに画像の説明を挿入

ステップ

  1. 初始标记:最初のマークは、GC Rootsが直接関連付けることができるオブジェクトをマークするためのものです。これは非常に高速で、STWが必要です。
  2. 并发标记:コード全体ですべてのオブジェクトをトラバースするのと同じです。これはワークロードが最大の場所ですが、このプロセスは同時ユーザースレッドに適しており、STWは使用されません。
  3. 重新标记:同時マーキング中のユーザープログラムの連続動作によりマーキングが変化したオブジェクトのマーキング記録を修正するため、この段階の休止時間は通常、初期マーキング段階よりわずかに長くなりますが、同時マーキング時間よりもはるかに短いです。それでもSTWする必要があります
  4. 并发清除:ガベージオブジェクトをクリアし、ユーザースレッドと同時に実行します

ステップの同時マーキングと同時クリアには最も時間がかかりますが、コレクタースレッドはユーザースレッドと一緒に機能します。そのため、一般的に、CMSコレクターのメモリー再利用プロセスはユーザースレッドと同時に実行されます。

(7)G1コレクター(唯一のフルエリアガベージコレクター)

ヒープメモリ全体が多くの小さな領域に分割されます。各領域は領域と呼ばれ、これらの領域は異なる役割に分割されます。GCの各ラウンドはその一部のみを処理する必要があり、GCの複数のラウンドの後に処理されます。 。メモリ領域全体。これにより、GC時間の各ラウンドが十分に短くなります。

ここに画像の説明を挿入

Eは、その領域がEdenメモリ領域に属していることを示します

Sは、サバイバーメモリ領域に属していることを示します

TはTenuredmemoryareaに属することを意味します

空白は未使用のメモリスペースを意味します

終了!

おすすめ

転載: blog.csdn.net/weixin_46103589/article/details/124369544