コンカレントGCでのNew領域の扱い

コンカレントGCは、Old領域にてアプリケーションを止めてしまうStop The WorldのGCではなく、アプリケーションを実行しつつGCを実行できるGCのタイプである。
コンカレントGCを利用した場合の設定が記述されているサイトをチェックすると、New領域はそれほど大きくせず、Old領域にすぐ移動させるという戦略をとっている場合が多い。これは、New領域のGCは、シリアルやパラレルのStop The World型のGCであるため、New領域のGC時間を小さくし、Old領域にオブジェクトを移動させてコンカレントGCにオブジェクトの回収を行わせたほうがよいということであろう*1 *2 *3
ただし、Sun製のコンカレントGCのではヒープ領域にフラグメントが発生するためそれを整理するために、mark and sweep タイプの(Full)GCが発生してしまうというリスクがある*4。また、System.gcを呼び出したときも同様に mark and sweep タイプのGCが発生する*5

*1:JDK1.6.0からNew領域の最小値が4Mから16Mに変更されているとのこと(参考文献:Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle)

*2:参考文献:Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle

*3:スループットをよくするためにNew領域を大きくしパラレルGCを採用し、Old領域ではコンカレントGCを利用するというパターンも考えられる(参考文献:Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle)

*4:FullGCのリスクに対しては、CMSInitiatingOccupancyFractionオプションでチューニングするらしい。。。参考文献 Oracle Technology Network for Java Developers | Oracle Technology Network | Oracle

*5:JDK1.6.0から-XX:+ExplicitGCInvokesConcurrentオプションを利用することでSystem.gc実行時に並列でGCが行うことができるようになっている