目次
仕様ではガベージ コレクターの実装方法が規定されていないため、ユーザーは必要に応じて組み合わせて使用できるように、さまざまな仮想マシンがさまざまなコレクターを提供します。
HotSpot 用のさまざまなコレクター:
2 つのコレクター間には接続があり、一緒に使用できることを示しています。これだけ多くの組み合わせが用意されているのは、それぞれのコレクターに一長一短があり、完璧なコレクターがまだ存在しないためです。
1、シリアル
これは新世代に使用される最もベーシックなコレクターであり、その名前は「シリアル」を意味します。
これはシングルスレッド コレクターです。つまり、ガベージ コレクションに 1 つのスレッドのみを使用します。
标记-复制
アルゴリズム。
その原理とプロセスは比較的単純ですが、スレッドを停止するアクションは仮想マシンによって開始されるため、ユーザー スレッドが不明であり、突然停止されるのはあまり良くありません。
後続のガベージ コレクターの主な目標は、ユーザー スレッドの一時停止時間を短縮することですが、一時停止を回避する方法は常にありません。
2、正規品
これは Serial のマルチスレッド並列バージョンです。デフォルトで有効になっているコレクション スレッドの数は CPU の数と同じです。並列ガベージ コレクションには複数のスレッドを同時に使用できます。
Serial を除けば、ParNew のみが CMS で動作します。CMS は画期的な意義を持ち、その後の ParNew は CMS に統合された新世代の専用コレクターと言えます。
标记-复制
アルゴリズム。
3、パラレルスカベンジ
また、新世代を対象としており、さまざまな懸念事項があるマルチスレッドの並列収集をサポートしています。
-
CMS などのコレクターの焦点は、ガベージ コレクション中のユーザー スレッドの一時停止時間を可能な限り短縮することです。
-
Parallel Scavenge の焦点は、
保证一个可控制的吞吐量
ユーザー エクスペリエンスを確保することです。(ここでのスループットとは、単位時間あたりのユーザー コードの実行時間 (ユーザー コードの実行 + ガベージ コレクション) の割合を指します)
スループットに重点を置いているため、Parallel Scavenge は「スループット優先コレクター」とも呼ばれます。
スループットが重要なシナリオ、またはプロセッサ リソースが不足しているシナリオに適しています。
标记-复制
アルゴリズム。
4、古いシリアル
これはシリアルの旧世代バージョンで、これもシングルスレッドで标记-整理
アルゴリズムを使用します。
5、パラレルオールド
これは Parallel Scavenge の旧世代バージョンで、マルチスレッドの同時収集をサポートし、标记-整理
アルゴリズムを使用します。
6、CMS
CMS (Concurrent Mark Sweet) は、最短回收停顿时间
「 」に到達することを目指すコレクターです。応答速度を重視するサーバーに最適です。
これは一般的なマークスイープ アルゴリズムよりも複雑で、次の 4 つの段階に分かれています。
- 初期マーク: Stop The World。GC ルートが直接関連付けることができるオブジェクトをマークします。これは高速です。
- 同時マーキング: GC ルート追跡マーキング プロセスは、ユーザー スレッドを一時停止することなく、ユーザー スレッドと同時に実行できます。
重新标记
: Stop The World は、マーキング中に生成されたオブジェクトの生存可能性を再判断し、これらのオブジェクトのマーキングを修正します。実行時間は同時マーキングよりも短くなります。- 同時クリア: オブジェクトのクリアはユーザー スレッドと同時に実行できます。
CMS是清理老年代的
。
1. 各段階でやるべきこと
イニシャルマーク
動作モード: JDK7 より前はシングルスレッド、JDK8 以降はマルチスレッド
目的: 生き残ったオブジェクトにマークを付ける
次の 2 つの部分が含まれます。
- GC ルートが直接関連付けることができる古い世代のオブジェクトにマークを付ける
- 新しい世代でまだ存続しており、古い世代への参照を含むオブジェクトにマークを付けます。つまり、新しい世代から古い世代への追加の世代間参照が考慮されます。
一時停止時間を短縮するには、初期マークの並列化 -XX:+CMSParallelInitialMarkEnabled を有効にし、同時マーク スレッドの数を増やすことができますが、CPU コアの数を超えないようにしてください。
同時マーキング
目的: 最初のマーキング フェーズでマークされた生き残ったオブジェクトを追跡し、すべての生き残ったオブジェクトを見つけます。
ユーザー スレッドと同時に実行されるため、期間中に次のアクションが発生する可能性があります。
- 新しい世代のオブジェクトは古い世代に昇格されます
- ラージオブジェクトを古い世代に直接割り当てる
- 旧世代のオブジェクト間の参照関係が変更される
これらのオブジェクトについては、現在の最新ステータスを再度マークする必要があります。そうしないと、残っているオブジェクトが見逃される可能性があります。
再マーキングの効率を向上させ、古い世代全体の再スキャンを避けるために、この段階で上記の動作を発見した後、オブジェクトが存在するカードがダーティ カードとしてマークされます。処理のためにスキャンする必要があります。
したがって、同時マーキング フェーズが完了した後、古い世代に残っているすべてのオブジェクトがマークされるわけではなく、一部はダーティ カードとして記録され、後続の処理を待機します。
前洗浄段階
目的: すべてのダーティ カードをスキャンし、ダーティ カード内のすべてのオブジェクトの参照関係を確認し、生き残ったオブジェクトにマークを付けます。
終了可能な前処理
目的: この段階では、再マーキング フェーズの実行を試みます。これは、再マーキング フェーズが停止するため、一時停止時間をいくらか短縮できるためです。
このフェーズの最大継続時間は 5 秒です。これは、新しい世代をクリーンアップするために若い gc がこの 5 秒以内に発生することが期待されているためです。これにより、次のフェーズで世代間の参照をスキャンする時間が短縮されます。
ラベルを付け直す
目的: 旧世代全体のすべての生物のマーキングを完了する、stw
再マーキングには 3 色マーキングで増分更新アルゴリズムを使用します。
チューニング:
この段階の目的は古い世代をマークすることですが、新しい世代に古い世代への世代間参照が存在する可能性があるため、ヒープ全体をスキャンする必要があります。
効率を高めるために、パラメーター -XX:+CMSScavengeBeforeRemark を追加して、再マークする前に若い gc を実行できます。
このようにして、小さい新しい世代のみをスキャンする必要があるため、効率が大幅に向上します。
同時クリーンアップ
1. なぜ 2 回も「世界を止める」必要があるのですか?
「初期マーキング」フェーズでは、CMS は GC ルートに直接関連付けることができるオブジェクトをすばやくスキャンし、一時停止を解除します。
その後、ユーザー スレッドと同時に実行され、オブジェクト到達可能性分析が実行されます。
ただし、ユーザースレッドの実行中に参照関係が変更される可能性があるため、ワールドを再度停止し、参照が変更されたオブジェクトのマークを変更します。
たとえば、オブジェクトが最初に「死んでいる」と判断され、その後ユーザー スレッドがそのオブジェクトとの参照関係を再確立すると、オブジェクトは 2 回目に「生きている」に変更されます。
注: 「初期マーキング」フェーズでマークされていないオブジェクトは、「リマーキング」フェーズではガベージ オブジェクトとしてマークされません。
このフェーズの一時停止時間は通常、最初のフェーズよりわずかに長くなりますが、同時マーキング時間よりははるかに短くなります。
プロセス全体の中で「同時マーキング」および「同時クリーニング」プロセスが最も長いため、コレクター スレッドはユーザー スレッドと連携して動作できます。したがって、一般に、CMS コレクターのメモリ再利用プロセスはユーザー スレッドと同時に実行されます。
利点: 同時収集、短い一時停止
2. CMS の同時実行によって引き起こされる問題
並行フェーズでは、ユーザー スレッドが一時停止することはありませんが、CPU の実行リソースの一部を占有するため、アプリケーションの速度が低下し、合計のスループットが低下します。
CMS によって開始されるリサイクル スレッドのデフォルトの数は、(プロセッサ コアの数 + 3)/4 です。プロセッサ コアの数が 4 つ未満の場合、CMS はユーザー プログラムに大きな影響を与えます。
3. CMS トリガーのタイミング
CMS コレクターは、他のコレクターのように、古い世代がほぼいっぱいになるまで待ってから収集することはできません。これは、 であるためですCMS需要预留足够的内存给用户线程使用
。
デフォルトのポリシーでは、古い世代がスペースの 68% を使用した後にリサイクルを開始します。
- ポリシーのしきい値を低く設定すると、ガベージ コレクションがより頻繁に発生し、パフォーマンスに影響します。
- ポリシーのしきい値の設定が高すぎる場合、および CMS によって予約されたメモリが新しいオブジェクトを割り当てるプログラムのニーズを満たすことができない場合、JVM は緊急計画を開始します。つまり、ユーザー スレッドの実行をフリーズし、Serial Old の再実行を一時的に有効にします。古い世代を廃棄するため、一時停止時間が非常に長くなります。
4. CMSの欠陥
- CMS コレクターはプロセッサ リソースに非常に敏感です。ユーザー スレッドは停止しませんが、プロセッサ リソースをめぐってユーザー スレッドと競合し、ユーザー スレッドの実行が遅くなるからです。
- CMS は「」を処理できないため
浮动垃圾
、GC で十分なスペースが生成されず、フル GC をトリガーする必要が生じる可能性があります。 - CMS は
标记-清除
アルゴリズムに基づいており、多数のアルゴリズムを生成します空间碎片
。オブジェクトの割り当てが影響を受ける場合は、メモリを整理するためにフル GC をトリガーする必要があります。 - CMS の実行中にユーザー スレッドが突然大量のガベージを生成した場合、JVM はユーザー スレッドを緊急に一時停止し、Serial Old を使用して古い世代を再度ガベージします。
浮遊ゴミとは
初めて「イニシャルマーク」が判定されたとき、その物体はゴミではありません。しかし、「リマーキング」の 2 回目の判定中に、このオブジェクトはガベージとなり、このガベージ コレクションでは処理できず、次の GC までリサイクルの機会を待つしかありません。この種のオブジェクトはフローティング ガベージです。
5. CMS はなぜ消去アルゴリズムを使用するのですか?
CMS では、ガベージ コレクションによるユーザー スレッドの一時停止時間を最小限に抑えることを考慮していますが、ワークロードは軽減できないため、特定の段階でユーザー スレッドとガベージ コレクションを同時に実行できるようにすることを検討してください。
このため、ユーザー スレッドが正常に実行されている場合、CMS は承認なしにオブジェクトのアドレスを変更できません。変更しない場合、ユーザー スレッドはオブジェクトを見つけることができません。
コピーアルゴリズムと照合アルゴリズムはどちらもオブジェクトのメモリアドレスを変更する必要があるため、適切ではありません。
7、G1
G1 はサーバー用の高性能ガベージ コレクターであり、主にマルチコア プロセッサーと大容量メモリを搭載したマシンをターゲットとしています。
JDK 1.9 では、G1 がデフォルトのガベージ コレクターとして使用され、CMS は「非推奨」としてマークされました。
G1 は GC 一時停止時間の要件を非常に高い確率で満たしますが、高いスループット パフォーマンス特性も備えています。
1、地域
G1 ヒープ メモリのレイアウトは他のコレクタとは異なります。
G1不再进行固定大小以及固定数量的分代区域划分,而是把连续的Java堆划分成多个大小相等的独立区域(Region)
。
領域のサイズは一定であり、その値は 1M バイトから 32M バイトまでの 2 のべき乗であり、JVM は領域を約 2048 個の領域に分割しようとします。
各リージョンは、ニーズに応じてエデン、サバイバー、または旧世代スペースの役割を果たすことができます。
G1 は、異なる役割を果たすリージョンに対して異なる収集戦略を使用できるため、新しく作成されたオブジェクトと古いオブジェクトの両方が良好な収集結果を達成できます。
リージョンには、大きなオブジェクトの保管に特化した特別なタイプの Humongous エリアもあります。
オブジェクトがリージョン容量の 50% を超える場合、そのオブジェクトは N 個の連続する巨大なリージョンに保存され、G1 のほとんどの動作はそれを古い世代の一部として扱います。
ヒープ メモリは断片化されているため、利用可能なすべての領域を記録するには空きリストを維持する必要があります。
2. 地域をデザインする意義
G1 には新世代と旧世代の概念がまだ存在しますが、それらは連続したものではなく、一連のリージョンの動的な集合です。
G1 が予測可能な停止時間モデルを確立するための基礎は、1 回のリサイクルの最小単位として地域を選択することです。
具体的な方法は、リージョンごとにゴミの蓄積の「価値」に基づいた優先順位リストを保持するというもの。価値には次の 2 つの側面が含まれます。
- リサイクル後に得られるスペースの量
- リサイクルにかかる時間
ゴミが収集されるたびに、根据用户指定的允许停顿时间,优先回收那些价值大的Region,保证了有限时间内的较高效率
。
これは、ガベージ コレクションの考え方の変更に相当します。
- これまでは、新世代の方がより多くのメモリを取得できることが多いため、新世代のリサイクルが優先されていましたが、新世代で足りない場合はヒープ全体が回収されていました。
- 現在は、リサイクル価値の高いメモリのリサイクルが優先されるため、これは積極的な行動であり、より対象を絞ったものであるため、効率は以前よりもはるかに高くなります。
3. G1の3つのモード
ヤングGC
すべての eden 領域が使い果たされてメモリを申請できない場合、若い gc がトリガーされます。ユーザー スレッドは一時停止され、複数のガベージ コレクション スレッドが開始されます。
存続するオブジェクトは存続領域にコピーされるか、古い領域に昇格されます。クリーンアップされた領域は空きリストに置かれ、次回使用されるのを待ちます。
混合 GC
以前のすべてのガベージ コレクターは、ガベージ コレクションの対象として、新しい世代、古い世代、またはヒープ全体を対象としていました。
より多くのオブジェクトが古いリージョンに昇格され、設定されたしきい値に達すると、混合 GC がトリガーされ、高価値のオブジェクトがリサイクルされます。
フル GC
オブジェクト メモリの割り当て速度が速すぎて、混合 gc をリサイクルする時間がなく、古い世代がいっぱいになった場合、完全な gc がトリガーされます。
G1 のフル GC アルゴリズムはシングル スレッドで実行されるシリアル オールド gc であり、ユーザー スレッドが長時間停止する原因となるため、フル GC を回避する必要があります。
4. 混合GCの操作手順
-
初期マークアップ:
- 世界を停止し、GC ルートが直接関連付けることができるオブジェクトをマークします
- さらに、次のステージのユーザー スレッドが使用可能なスペースに新しいオブジェクトを正しく割り当てることができるように、TAMS ポインターの値を変更します。
-
同時マーキング: GC ルートから開始して、ヒープ内のオブジェクトの到達可能性分析を実行します。ユーザースレッドと同時実行 (ユーザースレッドと同時実行できるのは同時マーキングフェーズのみ)
-
最终标记
:stop the world、並行フェーズ終了後に残った STAB レコードを処理します -
筛选回收
:- オブジェクトアドレスの変更を伴うため、ユーザーが設定した時間に従ってユーザースレッドを一時停止します。
- リージョンの価値を分類し、ユーザーの予想される停止時間に基づいてリサイクル計画を策定し、リサイクル回収を形成します
- 次に、リサイクルすることが決定されたリージョンの一部の残りのオブジェクトを空のリージョンにコピーし、古いリージョンのすべてのスペースをクリーンアップします。
5、カードテーブル
従来のガベージ コレクションで発生する世代間参照の問題は、G1 にも存在します。
G1 はヒープ全体を多くの領域に分割するため、各領域の異なるオブジェクトには相互参照の依存関係があり、異なる領域間でも同世代の参照が発生します。
リサイクルする前に正確なガベージコレクションを達成するためにすべての領域を横断する必要がある場合、効率は非常に低くなります。
G1でもRemember Setメモリーセットのアイデアを取り入れてCard Tableを作りました。
カードテーブルにはさまざまなリージョン間の参照関係が格納されているため、リージョン全体をスキャンすることなく、関連するリージョンのみをスキャンできます。
6. 3色マーキング方式
G1 は、CMS と同様に、同時マーキング フェーズで 3 色のマーキング方法を使用します。
入札漏れの問題
通常の参照関係は次のとおりです。
- オブジェクトのスキャンは灰色のノードとして完了します
- オブジェクトのメンバ変数、つまり参照関係にある他のオブジェクトをスキャンします。スキャンが完了すると、前のオブジェクトは黒いノードになります。
- まだスキャンされていないオブジェクトは白いノードとして表示されます。
- 同時マーキングフェーズ中にユーザースレッドがグレーノードと白ノード間の参照を削除した場合、グレーノードのメンバー変数をスキャンするときに白ノードはスキャンされず、ガベージとして扱われます。
- しかし、白ノードと黒ノードに参照がある場合、既存のスキャン方法ではその参照を検出できず、本来参照関係があるノードを見逃してしまう問題が発生する。
CMS と G1 は入札漏れの問題をどのように解決するか
入札漏れの問題が発生する条件は次の 2 つです。
- 黒いオブジェクトが白いオブジェクトを指しています (参照の増加に注意してください)
- 白いオブジェクトを指す灰色のオブジェクトの参照が消えます(参照の削除に注意)
したがって、入札漏れの問題を解決するには、2 つの条件のうち 1 つを破るだけで済みます。
- CMS が行うことは次のとおりです。
- 同時マーキング プロセスでは、「増分更新」メカニズムが使用され、新しい参照が生成されると、黒いノードが灰色でマークされ、後で再スキャンされて最新の参照関係が取得されます。
- 同時マーキングが完了した後、リサイクルされるオブジェクトの数は増加しません。
- 同時マーキングが完了すると、2 回目の一時停止がトリガーされ、参照関係が再確立されたオブジェクトがリサイクル範囲から移動されます。
- 同時マーキング中に生成された新しいガベージはリサイクルされません。
- G1 が行うことは次のとおりです。
- 同時マーキング段階で生成された新しいガベージは記録され、最終マーキング段階でリサイクル範囲に含まれます。
- 灰色→白が消えた場合、この参照を GC スタックにプッシュして、白が引き続き GC でスキャンできるようにする必要があります。
なぜ G1 は増分更新メカニズムを使用しないのですか?
黒いノードが灰色のノードとしてマークされていると、後で 2 回検索されることになり、非効率的になるためです。
G1 は、領域間の参照関係を格納するカード テーブルを保存します。
7、刺す
G1 は、オリジナルのスナップショット (STAB) アルゴリズムを使用して、Snapshot-At-The-Beginning を解決します。
具体的な手順は次のとおりです。
- GC が開始される前に、オブジェクト スナップショットを作成します。
- 同時マーキング中、その時点でスナップショット内に残っているすべてのオブジェクトは生きているとみなされます。マーキング プロセス中に新しく割り当てられたオブジェクトも生きているオブジェクトとしてマークされ、リサイクルされません。
GC とユーザー スレッドの同時動作を実現するには、リサイクル プロセス中に新しいオブジェクトの割り当てを解決する必要があるため、G1 はリージョン領域ごとに TAMS (Top at Mark Start) という名前の 2 つのポインタを設計し、一部を割り当てます。リージョン領域からのスペースの同時リサイクル中に新しいオブジェクトを記録するために使用されます。このようなオブジェクトは生きているとみなされ、ガベージ コレクションには含まれません。
8. G1の特徴
- 並列処理と同時実行性: G1 は、CPU およびマルチコア環境のハードウェアの利点を最大限に活用し、複数の CPU (CPU または CPU コア) を使用して Stop-The-World の一時停止時間を短縮できます。他の一部のコレクターでは、本来 Java スレッドによって実行される GC アクションを一時停止する必要がありますが、G1 コレクターでは Java プログラムが並行して実行を継続できるようにすることができます。
- 世代別コレクション: G1 は、他のコレクターの協力なしで GC ヒープ全体を独立して管理できますが、世代別コレクションの概念は依然として残っています。
- 空間統合:CMSの「マーククリーン」アルゴリズムとは異なり、 G1
从整体来看是基于“标记整理”算法
で実装されたコレクター从局部(两个Region之间)上来看是基于“复制”算法
が実装されているため、不会产生内存碎片
. - 予測可能な一時停止: これは CMS に対する G1 のもう 1 つの利点です。一時停止時間の短縮は G1 と CMS の共通の焦点ですが、G1 では
除了追求低停顿外,还能建立可预测的停顿时间模型
ユーザーが許容される一時停止時間を明確に指定できます。
8. JDK のデフォルトのガベージ コレクター
jdk1.7 デフォルトのガベージ コレクター: Parallel Scavenge (新世代) + Parallel Old (旧世代)
jdk1.8 デフォルトのガベージ コレクター: Parallel Scavenge (新世代) + Parallel Old (旧世代)
jdk1.9 のデフォルトのガベージ コレクター: G1