8.2.2 明示管理ヒープ機能の利用によるフルガーベージコレクションの抑止の仕組み

明示管理ヒープ機能では,Javaオブジェクトの配置先として,Explicitヒープという独自の領域を使用します。Explicitヒープは,Javaヒープ外にある,ガーベージコレクションの対象にならない領域です。明示管理ヒープ機能を使用していない場合にJavaヒープに配置していたJavaオブジェクトをExplicitヒープに配置することによって,フルガーベージコレクションが発生することを抑止できます。

ここでは,明示管理ヒープ機能を利用してフルガーベージコレクションを抑止する仕組みについて説明します。また,明示管理ヒープ機能の位置づけについてもあわせて説明します。

<この項の構成>
(1) フルガーベージコレクション発生を抑止する仕組み
(2) 明示管理ヒープ機能の位置づけ
(3) 明示管理ヒープ機能を使用する場合に必要なメモリサイズ

(1) フルガーベージコレクション発生を抑止する仕組み

Javaアプリケーション実行中にEden領域に空き領域がなくなると,ガーベージコレクションが発生します。このとき,次の式が成り立つ場合は,JavaVMによってフルガーベージコレクションが実行されます。

New領域で使用されているメモリのサイズ>Tenured領域の空き領域のサイズ

Eden領域に空き領域がなくなっているため,New領域で使用されているメモリのサイズはNew領域の最大サイズにほぼ等しくなります。

式が示すとおり,Tenured領域の空き領域のサイズが小さくなるとフルガーベージコレクションが発生します。Tenured領域の空き領域は,コピーガーベージコレクションが発生したときにSurvivor領域から移動(昇格)するJavaオブジェクトによって使用されます。つまり,昇格するJavaオブジェクトを削減できれば,フルガーベージコレクションの発生を抑えられます。なお,何回かのコピーガーベージコレクションの実行で削除されないで,昇格の対象になるオブジェクトを長寿命オブジェクトといいます。

長寿命オブジェクトには大きく分けて2種類あります。一つは,フルガーベージコレクションで回収されないオブジェクトです。例えばアプリケーションの実行中は常に生存し続けるような,本来Tenured領域に格納される必要があるオブジェクトが当てはまります。このようなオブジェクトは増加し続けることはないため,フルガーベージコレクションが発生する本質的な原因ではありません。このような長寿命オブジェクトの影響を排除したい場合は,Tenured領域のサイズを増加することで対処できます。

二つ目は,フルガーベージコレクションで回収されるオブジェクトです。フルガーベージコレクションで回収される長寿命オブジェクトとは,Tenured領域に昇格する程度に長寿命であるが,一定期間で不要となるオブジェクトを指します。このような長寿命オブジェクトはフルガーベージコレクションの発生までは増加し続けるため,フルガーベージコレクション発生の原因となります。

フルガーベージコレクションで回収されるオブジェクト,およびフルガーベージコレクションで回収されないオブジェクトについて,次の図で説明します。

図8-1 フルガーベージコレクションで回収されるオブジェクト,およびフルガーベージコレクションで回収されないオブジェクト

[図データ]

一定期間で不要となるオブジェクトの増加を防ぐ対策として,Tenured領域のサイズを増加しただけでは,効果がありません。Tenured領域のサイズを2倍にしても,フルガーベージコレクションの発生間隔が2倍になるだけで,期待するほどの効果は得られません。

つまり,フルガーベージコレクションの発生を抑止するためには,一定期間で不要となるオブジェクトのTenured領域への昇格を減らすことがポイントとなります。

アプリケーションサーバでは,一部のJavaオブジェクトについて,コピーガーベージコレクション発生時の昇格先がExplicitヒープになるように設定されています。明示管理ヒープ機能を使用していない場合の昇格と明示管理ヒープ機能を使用している場合の昇格の違いを次の図に示します。

図8-2 明示管理ヒープ機能を使用していない場合の昇格と明示管理ヒープ機能を使用している場合の昇格の違い

[図データ]

図の1.のタイミングでは,どちらの場合も同じ状態です。2.のオブジェクトが昇格するタイミングで,明示管理ヒープ機能を使用していない場合の昇格では,すべての長寿命オブジェクトがTenured領域に移動します。一方,明示管理ヒープ機能を使用している場合,長寿命オブジェクトのうち,一定期間後に破棄されることがわかっているオブジェクトについてはExplicitヒープに移動します。これによって,Tenured領域に移動するのは,破棄される予定がない長寿命オブジェクトに限定され,Tenured領域の使用済みサイズの増加が緩やかになります。なお,3.で示すとおり,明示管理ヒープ機能を使用している場合のExplicitヒープのオブジェクトは,不要になったタイミングで削除されます。

対象となるJavaオブジェクトについては,「8.4 J2EEサーバ利用時にExplicitヒープに配置されるオブジェクト」を参照してください。また,ガーベージコレクションのアルゴリズムについては,マニュアル「Cosminexus アプリケーションサーバ システム設計ガイド」の「7. JavaVMのメモリチューニング」を参照してください。

なお,ユーザが開発するアプリケーションで明示管理ヒープ機能を使用する場合は,一定期間後に破棄される長寿命オブジェクトを,直接Explicitヒープに生成します。これによって,Tenured領域のメモリサイズ増加を防ぎます。Explicitヒープに生成できるJavaオブジェクトについては,「8.5 アプリケーションで任意にExplicitヒープに配置できるオブジェクト」を参照してください。

(2) 明示管理ヒープ機能の位置づけ

明示管理ヒープ機能は,日立のJavaVMの機能です。明示管理ヒープ機能を利用する方法には,次の2種類があります。

明示管理ヒープ機能の位置づけを次の図に示します。

図8-3 明示管理ヒープ機能の位置づけ

[図データ]

明示管理ヒープ機能の範囲である,明示管理ヒープ機能API,自動配置設定ファイル,明示管理ヒープ機能を構成する各機能,Tenured領域内不要オブジェクト統計機能,およびExplicitヒープについて説明します。

自動配置設定ファイル
Javaプログラムを変更しないで明示管理ヒープ機能を使用する場合,自動配置設定ファイルを使用します。このファイルに明示管理ヒープに配置させたいオブジェクトを指定します。
明示管理ヒープ機能API
Javaプログラムから明示管理ヒープ機能を使用する場合,明示管理ヒープ機能APIを使用します。このAPIでは,Explicitヒープに関連する操作が実行できます。また,Explicitヒープの使用状況を稼働情報として収集することもできます。
明示管理ヒープ機能を構成する各機能
明示管理ヒープ機能を構成する各機能は,JavaVMに含まれます。APIで呼び出されます。次の処理を実行できます。
  • Explicitヒープおよびヒープ内のメモリブロックの管理および制御
  • ガーベージコレクションと連携したアロケーション処理の変更によるExplicitヒープへのオブジェクトの配置
    なお,アロケーション処理はnewキーワードの延長で実行されます。
  • 日立JavaVMログファイルとスレッドダンプへのExplicitヒープのイベントログおよび状態の出力
Tenured領域内不要オブジェクト統計機能
Tenured領域内でメモリ増加の原因となっている不要オブジェクトを調査します。Tenured領域内不要オブジェクト統計機能については,マニュアル「Cosminexus アプリケーションサーバ 機能解説 保守/移行/互換編」の「8.8 Tenured領域内不要オブジェクト統計機能」を参照してください。
Explicitヒープ
ガーベージコレクションの対象外にするJavaオブジェクトの配置先になる領域です。明示管理ヒープ機能が管理します。Explicitヒープは,複数のメモリブロック(Explicitメモリブロック)で構成されます。

(3) 明示管理ヒープ機能を使用する場合に必要なメモリサイズ

明示管理ヒープ機能で管理するExplicitヒープは,Javaヒープ外の領域です。Explicitヒープを使用する場合,使用しない場合に比べて,メモリの使用量が増加します。

明示管理ヒープ機能を使用する場合は,必要なメモリサイズとしてExplicitヒープの最大サイズを見積もり,適切に設定する必要があります。明示管理ヒープ機能を利用する流れ,Explicitヒープに格納するオブジェクト(Tenured領域のメモリサイズ増加の要因になるオブジェクト),およびExplicitヒープのサイズの見積もりについては,マニュアル「Cosminexus アプリケーションサーバ システム設計ガイド」の「7.10 Explicitヒープのチューニング」を参照してください。