7.15.5 メモリ空間とリージョンの関係
G1GCで管理するJavaヒープ領域は,オブジェクトの寿命が短いオブジェクトが格納されるNew領域と,寿命が長いオブジェクトが格納されるTenured領域に分けて管理します。このうちNew領域はさらに2つの領域に分けて管理されており,作成されたばかりのオブジェクトが格納されるEden領域と,1回以上のGCの対象になり,回収されなかったオブジェクトが格納されるSurvivor領域に分けられます。New領域内で一定回数以上のGCの対象になったオブジェクトは,寿命が長いオブジェクトと判断され,Tenured領域に移動します。
アプリケーション実行中のG1GCで管理するメモリ空間の構成を次の図に示します。なお,Eden領域,Survivor領域,Tenured領域,Free領域を合わせた領域をJavaヒープ領域といいます。
G1GCでは,Tenured領域があらかじめ割り当てられていません。Tenured領域にオブジェクトを移動させる場合,Free領域のリージョンをTenured領域に割り当ててオブジェクトを移動します。また,G1GCではGC後にNew領域に対して拡張や縮小をします(以降,リサイズ)。リサイズでNew領域を拡張する場合は,Free領域のリージョンに割り当て,縮小する場合はNew領域のリージョンを回収し,Free領域に割り当てます。サイズの大きなオブジェクトを作成する場合は,Humongous領域にオブジェクトが格納されます。
各領域の用途を次に示します。
-
New領域
寿命が短いオブジェクトが格納される領域です。Eden領域とSurvivor領域から構成されます。GC後に次のGCに向けてリサイズされます。詳細については,「7.15.8 YoungGC」を参照してください。
-
Eden領域
作成されたオブジェクトが最初に格納される領域です。
-
Survivor領域
New領域に格納されていたオブジェクトのうち,GC実行時に回収されなかったオブジェクトが格納される領域です。Survivor領域はFrom空間とTo空間で構成されます。From空間とTo空間は同じサイズです。
-
Tenured領域
寿命が長いオブジェクトが格納される領域です。Survivor領域で指定回数を超えてGC実行対象になり,回収されなかったオブジェクトが移動します。
-
Humongous領域
Tenured領域の一部でサイズの大きなオブジェクトを格納する領域です。Humongous領域のオブジェクトは,FullGCまたはConcurrent Cleanupで回収されます。Concurrent Cleanupの詳細については,「7.15.9 Concurrent Marking(CM)」を参照してください。
-
Free領域
New領域やTenured領域に割り当てられていない領域です。Tenured領域のリージョンが足りなくなった場合やGC後のNew領域をリサイズする場合に,New領域やTenured領域に割り当てられます。
-
Metaspace領域
ロードされたclassなどの情報を格納する領域です。なお,Metaspace領域はリージョン単位で管理されていません。Metaspace領域のオブジェクトはFullGCでだけ回収されます。
図7-22はJavaヒープ領域の各領域を連続領域として表現していますが,実際には各領域は連続領域として確保されていません。G1GCではJavaヒープ領域をリージョンと呼ばれるブロック単位で管理しており,次の図のように領域が分散して確保されています。
ここではそれぞれの領域のリージョンを領域名+リージョンと表記します。例えば,Eden領域のリージョンをEdenリージョン,New領域のリージョンはNewリージョンと表記します。