GC アルゴリズム ガベージ コレクター
概要
ガベージ コレクション ガベージ コレクションは、1960 年に MIT の Lisp 言語で誕生しました。半世紀以上を経て、現在では非常に成熟しています。
jvm では、プログラム カウンター、仮想マシン スタック、およびローカル メソッド スタックはすべてスレッドによって生成および破棄され、メソッドの出入り時にスタック フレームがプッシュおよびポップされ、メモリの自動クリーニングが実現されます。コレクションは主に Java ヒープとメソッド領域に集中します。プログラムの実行中、この部分のメモリの割り当てと使用は動的に行われます。メソッド:
参照カウント: 各オブジェクトには参照カウント属性があり、参照が追加されるとカウントが 1 ずつ増加し、参照が解放されるとカウントが 1 ずつ減少します。リサイクルされる。この方法は単純ですが、オブジェクトが相互に循環参照する問題は解決できません。
到達可能性分析: GC ルートから下方向に検索します。検索によって移動するパスは参照チェーンと呼ばれます。オブジェクトに GC ルートに接続された参照チェーンがない場合、そのオブジェクトは使用できないことがわかります。到達不可能なオブジェクト。
Java 言語では、GC ルートには以下が含まれます:
仮想マシン スタックで参照されるオブジェクト。
メソッド領域のクラス静的プロパティ エンティティによって参照されるオブジェクト。
メソッド領域の定数によって参照されるオブジェクト。
ローカル メソッド スタック内の JNI によって参照されるオブジェクト。
ガベージ コレクション アルゴリズム
マーク スイープ アルゴリズム
「マーク スイープ」アルゴリズムは、その名前が示すように、「マーク」と「スイープ」の 2 つの段階に分かれています。最初にマークアウトします。必要なすべてのオブジェクトです。リサイクル対象となるものは、マーキング完了後、一律にリサイクルされます。これが最も基本的な収集アルゴリズムであると言われる理由は、その後の収集アルゴリズムがこの考え方に基づいており、欠点が改善されているためです。
その主な欠点は 2 つあります。1 つは効率の問題であり、マーキングとクリアのプロセスはあまり効率的ではありません。もう 1 つは、マークとクリアの後に大量の不連続なメモリ フラグメントが生成されることです。フラグメントは、プログラムが将来より大きなオブジェクトを割り当てる必要がある場合に、十分な連続メモリを見つけることができず、事前に別のガベージ コレクション アクションをトリガーする必要がある場合に発生する可能性があります。
コピーアルゴリズム「コピー」(コピー)コレクションアルゴリズムでは、利用可能なメモリを容量に応じて2つの等しいサイズのブロックに分割し、一度にそのうちの1つだけを使用します。このメモリ ブロックが使い果たされると、残っているオブジェクトを別のブロックにコピーし、使用されているメモリ領域を一度にクリーンアップします。これにより、メモリを割り当てる際にメモリの断片化などの複雑な状況を考慮する必要がなく、ヒープの先頭ポインタを順番に移動するだけで簡単に実装できます。そして効率的に実行できます。ただ、このアルゴリズムのコストはメモリを元のサイズの半分に減らすことであり、存続期間の長いオブジェクトを継続的にコピーすると効率の低下につながります。
マーク圧縮アルゴリズム
コピー収集アルゴリズムは、オブジェクトの生存率が高い場合、より多くのコピー操作を実行するため、効率が低くなります。さらに重要なのは、スペースの 50% を無駄にしたくない場合は、使用されるメモリ内のすべてのオブジェクトが 100% 生きているという極端な状況に対処するために、割り当てを保証するための追加のスペースが必要であるため、この種の割り当てが必要になります。古い世代のアルゴリズムでは直接使用できません。
旧世代の特性に基づいて、誰かが別の「Mark-Compact」アルゴリズムを提案しました。マーキングプロセスは依然として「Mark-Clear」アルゴリズムと同じですが、その後のステップはリサイクル可能なものを直接クリーンアップするものではありません。代わりに、残っているすべてのオブジェクトが一方の端に移動され、その後、端の境界の外側にあるメモリが直接クリーンアップされます
世代別コレクションアルゴリズム
GC 生成の基本的な前提: ほとんどのオブジェクトのライフサイクルは非常に複雑です。短い生存時間。
「世代別収集」アルゴリズムは、Javaヒープを新世代と旧世代に分割し、各世代の特性に応じて最適な収集アルゴリズムを使用することができます。新しい世代では、ガベージ コレクションが実行されるたびに、多数のオブジェクトが消滅し、少数のオブジェクトだけが生き残ることがわかります。その後、コピー アルゴリズムを使用し、少数の生き残ったオブジェクトのコピー コストのみを支払う必要があります。コレクションを完成させるために。旧世代では、オブジェクトの生存率が高く、その割り当てを保証するための余分なスペースがないため、リサイクルには「mark-clean」または「mark-clean」アルゴリズムを使用する必要があります。
ガベージコレクター
コレクションアルゴリズムがメモリリサイクルの方法論である場合、ガベージコレクターはメモリリサイクルの具体的な実装です
シリアルコレクター
シリアルコレクターは最も古く、最も安定していて効率的です。長い一時停止が発生し、収集に 1 つのスレッドのみが使用される場合があります。新世代と旧世代はシリアル リサイクルを使用します。新世代のコピー アルゴリズム、旧世代のマーク圧縮はガベージ コレクション プロセス中に停止されます
パラメータ制御: -XX:+UseSerialGC Serialコレクター
ParNew Collector
ParNew Collector は、実際には Serial Collector のマルチスレッド バージョンです。新世代パラレル、旧世代シリアル、新世代コピーアルゴリズム、旧世代マーク圧縮
パラメータ制御: -XX:+UseParNewGC ParNew コレクター
-XX:ParallelGCThreads スレッド数を制限します
パラレル コレクター
パラレル スカベンジ コレクターは、ParNew コレクターに似ており、システムのスループットにさらに注意を払います。適応調整戦略はパラメータを通じて有効にすることができ、仮想マシンはシステムの現在の動作条件に基づいてパフォーマンス監視情報を収集し、これらのパラメータを動的に調整して、最適な一時停止時間や最大スループットを提供することもできます。ミリ秒または比率を超えないようにパラメータで制御します。新世代のコピー アルゴリズム、旧世代のマーク圧縮
パラメータ制御: -XX:+UseParallelGC パラレル コレクター + 旧世代のシリアルを使用します
Parallel Old コレクター
Parallel Old Parallel Scavenge コレクション マルチスレッドと「マーク アンド ソート」アルゴリズムを使用する、旧世代バージョンのサーバーです。このコレクターは、JDK 1.6 でのみ
パラメーター制御を提供し始めました: -XX:+UseParallelOldGC 並列コレクター + 旧世代の並列を使用します
CMS コレクター
CMS (Concurrent Mark Sweet) コレクターは、最短のコレクションを持つコレクターを取得します一時停止時間を目標にします。現在、Java アプリケーションの大部分はインターネット Web サイトや B/S システムのサーバーに集中しており、このようなアプリケーションはサービスの応答速度に特別な注意を払っており、ユーザーにサービスを提供するためにシステムの停止時間が最短であることを望んでいます。より良い体験を。
その名前 (「マーク スイープ」を含む) から、CMS コレクターは「マーク スイープ」アルゴリズムに基づいて実装されていることがわかります。その操作プロセスは、以前のコレクターよりも複雑で、プロセス全体が 4 つのステップに分かれています。
初期マーク (CMS 初期マーク)
同時マーク (CMS 同時マーク)
リマーク (CMS リマーク)
同時スイープ (CMS 同時スイープ)
このうち、初期マーク、再マークの両方をマークステップにはまだ「Stop The World」が必要です。初期マーキングは GC ルートが直接関連付けることができるオブジェクトのみをマーキングし、非常に高速です。同時マーキング フェーズは GC ルート トレースのプロセスであり、再マーキング フェーズはユーザー プログラムの継続によって発生したマーキングを修正します。変更されたオブジェクトの部分のマーキング記録の場合、この段階の一時停止時間は通常、最初のマーキング段階よりわずかに長くなりますが、同時マーキング時間よりははるかに短くなります。
コレクター スレッドは、プロセス全体で最長の同時マーキングおよび同時クリア処理中にユーザー スレッドと連携して動作できるため、通常、CMS コレクターのメモリ リサイクル プロセスはユーザー スレッドと同時に実行されます。旧世代のコレクター (新世代では ParNew が使用されます)
利点: 同時収集、短い一時停止
欠点: 大量のスペース フラグメントの生成、同時フェーズによりスループットが低下します
パラメーター制御: -XX:+UseConcMarkSoupGC CMS を使用コレクター
-XX:+UseCMSCompactAtFullCollection フル GC の後にデフラグを実行すると、デフラグ プロセスが排他的になるため、一時停止時間が長くなります
-XX: + - ParallelCMSThreads CMS スレッドの数を設定します (通常は次の値にほぼ等しい)利用可能な CPU の数)
G1 コレクター
G1 は、現在のテクノロジー開発の最も最先端の成果の 1 つであり、HotSpot 開発チームによって与えられた使命は、将来 JDK1.5 でリリースされた CMS コレクターを置き換えることです。 CMS コレクターと比較すると、G1 コレクターには次の特徴があります:
1. スペース統合 G1 コレクターはマークソートアルゴリズムを使用し、メモリスペースの断片化を生成しません。大きなオブジェクトを割り当てる場合、連続した領域が見つからないため、次の GC は事前にトリガーされません。
2. G1 のもう 1 つの大きな利点である予測可能な一時停止。一時停止時間の短縮は、G1 と CMS の共通の焦点です。ただし、G1 は、短い一時停止を追求することに加えて、予測可能な一時停止モデルを確立することもできます。作成者は、長さ N ミリ秒の時間セグメント内でガベージ コレクションにかかる時間が N ミリ秒を超えないよう明示的に指定しています。これは、リアルタイム Java (RTSJ) ガベージ コレクタのほぼ特性です。
上記のガベージコレクターは新世代または旧世代全体を収集するだけですが、G1 はそうではなくなりました。 G1 コレクターを使用する場合、Java ヒープのメモリ レイアウトは他のコレクターとは大きく異なります。ただし、新世代と旧世代の概念は変わりません。ただし、新しい世代と古い世代は物理的に分離されておらず、両方とも部分的な (不連続な場合もある) リージョンの集合です。
G1 の新世代のコレクションは、ParNew と同様に、新世代の占有率が一定の割合に達すると、コレクションが開始されます。 CMS と同様に、G1 コレクターが古い世代のオブジェクトを収集するときに短い一時停止が発生します。
収集手順:
1. マーキングフェーズ、最初の初期マーク (Initial-Mark)、このフェーズは一時停止され (Stop the World Event)、通常の Mintor GC がトリガーされます。 GC ログ: GC 一時停止 (若い) (初期マーク)
2、ルート領域スキャンに対応し、プログラムの実行中に生存領域がリサイクルされます (古い世代まで存続します)。このプロセスは若い GC の前に完了する必要があります。
3. 同時マーキングは、ヒープ全体で同時マーキングを実行します (アプリケーションと同時に実行されます)。このプロセスは若い GC によって中断される可能性があります。同時マーキング フェーズ中に、エリア オブジェクト内のすべてのオブジェクトがガベージであることが判明した場合、そのエリアはすぐにリサイクルされます (図の X)。同時に、同時マーキング プロセス中に、各領域のオブジェクトのアクティビティ (領域内で生き残っているオブジェクトの割合) が計算されます。
4. 短い一時停止 (STW) がありますのでご注意ください。再マーキング フェーズは、同時マーキング フェーズによって生成された新しいガベージを収集するために使用されます (同時フェーズはアプリケーションとともに実行されます)。G1 は、CMS よりも高速な初期スナップショット アルゴリズム、つまりスナップショット アット ザ ビギニング (SATB) を使用します。 。
5. コピー/クリーンアップ、非アクティブなオブジェクトをクリアするマルチスレッド、STW があります。 G1 は、リサイクル領域に残っているオブジェクトを新しい領域にコピーし、セットの記憶をクリアし、同時にリサイクル領域をクリアしてフリー領域のリンク リストに戻します。
6. コピー/クリア処理後。リサイクル領域のアクティブなオブジェクトは、濃い青と濃い緑の領域に集中しています。
よく使われるコレクターの組み合わせ