Hitachi

Cosminexus V11 アプリケーションサーバ 機能解説 拡張編


7.8.2 自動解放機能が無効な場合のExplicitメモリブロックの解放処理

解放処理は,事前に解放予約されているExplicitメモリブロックに対して実行されます。不要になったExplicitメモリブロックは,解放処理によってメモリから実際に削除されます。

〈この項の構成〉

(1) 実行契機

解放処理は,次の契機でJavaVMによって実行されます。

(2) 実行される内容

CopyGCまたはFullGCの処理が終了したあと,JavaVMによって解放予約されたExplicitメモリブロックがあるかどうかが調査されます。該当するExplicitメモリブロックが一つ以上ある場合は,そのExplicitメモリブロックが解放されます。解放は,OSのメモリ解放APIで実行されます。その際,解放されたExplicitメモリブロック内のオブジェクトは,破棄されます。

ただし,解放するExplicitメモリブロック内のオブジェクトのうち,どこからも参照されていないfinalizeメソッドを実装しているクラスのオブジェクトは,破棄されません。このオブジェクトは,ファイナライズキューに登録され,Javaヒープに移動されます。

また,解放対象のExplicitメモリブロックのオブジェクトが次の条件に該当する場合は動作が異なります。

(a) 外部(解放対象のExplicitメモリブロック以外)から参照されている場合

解放対象のExplicitメモリブロックのオブジェクトが,次の領域のオブジェクトから参照されている場合が該当します。

  • Javaヒープ

  • Metaspace領域

  • 解放対象でないExplicitメモリブロック

それぞれの場合に実行される内容を次に示します。

JavaヒープまたはMetaspace領域から参照されている場合

JavaヒープまたはMetaspace領域内のオブジェクトから参照されている場合,そのオブジェクトは破棄されません。

該当するオブジェクトは,JavaヒープのTenured領域に優先的に移動されます。ただし,Tenured領域に空き容量がない場合,またはTenured領域があふれた場合は,New領域に移動されます。また,すでに使用されていないTenured領域のオブジェクトから参照されている場合も,移動の対象になります。

解放対象ではないExplicitメモリブロックから参照されている場合

解放対象ではないExplicitメモリブロック内のオブジェクトから参照されている場合,そのオブジェクトは破棄されません。また,参照元のオブジェクトが解放対象のExplicitメモリブロック内のオブジェクトである場合も,そのオブジェクトが破棄されないでJavaヒープに移動するオブジェクトである場合は,参照されているオブジェクトも削除されません。

Explicitメモリブロック解放時に外部から参照されている場合の動作を次の図に示します。

図7‒13 Explicitメモリブロック解放時に外部から参照されている場合の動作

[図データ]

解放対象のExplicitメモリブロックに含まれるオブジェクトである,オブジェクトXを例にして説明します。

解放対象のExplicitメモリブロックのオブジェクトから参照されている場合,オブジェクトXは削除されます。

Javaヒープ,Metaspace領域または解放対象でないExplicitメモリブロックのオブジェクトから参照されている場合,オブジェクトXは削除されません。

また,オブジェクトXが解放対象のExplicitメモリブロックのオブジェクト(オブジェクトY)から参照されている場合も,参照元であるオブジェクトYがJavaヒープ,Metaspace領域または解放対象でないExplicitメモリブロックのオブジェクトから参照されているときには,オブジェクトXは削除されません。この場合,オブジェクトXは,オブジェクトYとともにJavaヒープに移動します。

(b) Javaヒープへのオブジェクト移動時にJavaヒープがあふれた場合

外部から参照されているオブジェクトがJavaヒープに移動するときに,移動先のJavaヒープに空き領域がなくなり,移動できなくなった場合が該当します。

この場合は,FullGCが実行され,Javaヒープに空き領域が確保されます。FullGC実行後,Javaヒープへのオブジェクトの移動が実行されます。

(c) FullGCで十分な空き領域を作成できない場合

Javaヒープに空き領域がなくなり,FullGCを実行してもJavaオブジェクトを移動するために必要な空き領域が確保できない場合が該当します。この場合は,Cヒープ不足の場合と同様に,JavaVMがアボートします。ただし,Cヒープ不足時には「request nnn bytes」としてnnnに必要なメモリサイズが出力されますが,JavaVMのアボート時には,nnnとして常に「0」が出力されます。