ヒープ領域がいっぱいになったときに一気にGCを行う方法。 欠点はヒープサイズが大きくなるに従いGC時間が長くなっていく。
ヒープ領域が「新しいオブジェクト(NEW)」領域と「古いオブジェクト(OLD)」領域に分けられている。新規に作成されたオブジェクトはNEW領域に配置され、NEW領域がいっぱいになった段階で、NEW領域内部だけのGCが走る(これをScavenge(廃品回収型)GCと呼ぶ)。Scavenge GCは「コピーイング」方式を採っており、「マーク・コンパクト」方式より低負荷・高速であるが、メモリ効率が悪いという欠点がある。
Scavenge GCで一定回数(32回)生き残ったオブジェクトは、「殿堂入り(Tenure)」して、OLD領域に移る。そして、OLD領域がいっぱいになると「マーク・コンパクト」方式によるFull GCが走ることになる。
一時的に作成したような寿命の短いオブジェクトは、通常32回のScavenge GCの間に消滅するので、殿堂入りしてOLD領域にいくことはまずない。コネクションプールやスレッドプールなどのリソースや、HttpSessionに格納されたオブジェクト、キャッシュなどが殿堂入りしてOLD領域に入る候補となる。また、それ以外では、あってはならないことだが、メモリリークしたオブジェクトもOLD領域に入ってしまう。
OLD領域は、寿命の長いオブジェクトの置き場所である。OLD領域がいっぱいになると、Full GCが走り、長時間の無応答状態が起きてしまうため、ここがいっぱいになってしまうことは避けなければならない。
http://www.atmarkit.co.jp/ait/articles/0211/30/news002.html
GCを次の4つのフェイズに分割して処理することで、その期間を最小化している。
生存オブジェクトをたどるための出発点(root)となるオブジェクトをマークする。rootとなるオブジェクトは限られているため、マーキングはすぐに終了 すべてのアプリケーションスレッドを停止させる必要がある
アプリケーションスレッドと並列に、rootからたどれるオブジェクトに対してマーキングを進める。並列に実行しているため以下のような状況が発生 マークしたオブジェクトに新たにオブジェクトの参照が追加され、生存しているのにマークされていないオブジェクトが存在 マークしたオブジェクトが使われなくなり、回収漏れとなるオブジェクトが存在
Concurrent Markフェイズで実施したマーキングの整合性を確保する 新たに追加されたオブジェクトの参照をチェックし、マーク漏れをなくす マークしたオブジェクトが不要になっていたとしても、次回のGCで回収されることを期待し、何も行わない すべてのアプリケーションスレッドを停止させる必要がある
マーキングされていないオブジェクトは参照がなくなったと判断されるため、それらを回収し空き領域を作成 アプリケーションスレッドと並列に行われる
http://www.atmarkit.co.jp/ait/articles/0704/24/news136.html
http://www.nminoru.jp/~nminoru/java/cms/concurrent_mark_sweep.html