解放処理は,事前に解放予約されているExplicitメモリブロックに対して実行されます。不要になったExplicitメモリブロックは,解放処理によってメモリから実際に削除されます。
解放処理は,次の契機でJavaVMによって実行されます。
コピーガーベージコレクションまたはフルガーベージコレクションの処理が終了したあと,JavaVMによって解放予約されたExplicitメモリブロックがあるかどうかが調査されます。該当するExplicitメモリブロックが一つ以上ある場合は,そのExplicitメモリブロックが解放されます。解放は,OSのメモリ解放APIで実行されます。その際,解放されたExplicitメモリブロック内のオブジェクトは,破棄されます。
ただし,解放するExplicitメモリブロック内のオブジェクトのうち,どこからも参照されていないfinalizeメソッドを実装しているクラスのオブジェクトは,破棄されません。このオブジェクトは,ファイナライズキューに登録され,Javaヒープに移動されます。
また,解放対象のExplicitメモリブロックのオブジェクトが次の条件に該当する場合は動作が異なります。
解放対象のExplicitメモリブロックのオブジェクトが,次の領域のオブジェクトから参照されている場合が該当します。
それぞれの場合に実行される内容を次に示します。
Explicitメモリブロック解放時に外部から参照されている場合の動作を次の図に示します。
図8-14 Explicitメモリブロック解放時に外部から参照されている場合の動作
解放対象のExplicitメモリブロックに含まれるオブジェクトである,オブジェクトXを例にして説明します。
解放対象のExplicitメモリブロックのオブジェクトから参照されている場合,オブジェクトXは削除されます。
Javaヒープ,Permanent領域または解放対象でないExplicitメモリブロックのオブジェクトから参照されている場合,オブジェクトXは削除されません。
また,オブジェクトXが解放対象のExplicitメモリブロックのオブジェクト(オブジェクトY)から参照されている場合も,参照元であるオブジェクトYがJavaヒープ,Permanent領域または解放対象でないExplicitメモリブロックのオブジェクトから参照されているときには,オブジェクトXは削除されません。この場合,オブジェクトXは,オブジェクトYとともにJavaヒープに移動します。
外部から参照されているオブジェクトがJavaヒープに移動するときに,移動先のJavaヒープに空き領域がなくなり,移動できなくなった場合が該当します。
この場合は,フルガーベージコレクションが実行され,Javaヒープに空き領域が確保されます。フルガーベージコレクション実行後,Javaヒープへのオブジェクトの移動が実行されます。
Javaヒープに空き領域がなくなり,フルガーベージコレクションを実行してもJavaオブジェクトを移動するために必要な空き領域が確保できない場合が該当します。この場合は,Cヒープ不足の場合と同様に,JavaVMがアボートします。ただし,Cヒープ不足時には「request nnn bytes」としてnnnに必要なメモリサイズが出力されますが,JavaVMのアボート時には,nnnとして常に「0」が出力されます。