明示管理ヒープ機能では,Javaオブジェクトの配置先として,Explicitヒープという独自の領域を使用します。Explicitヒープは,Javaヒープ外にある,GCの対象にならない領域です。明示管理ヒープ機能を使用していない場合にJavaヒープに配置していたJavaオブジェクトをExplicitヒープに配置することで,FullGCが発生することを抑止できます。
ここでは,明示管理ヒープ機能を利用してFullGCを抑止する仕組みについて説明します。また,明示管理ヒープ機能の位置づけについてもあわせて説明します。
Javaアプリケーション実行中にEden領域に空き領域がなくなると,GCが発生します。このとき,次の式が成り立つ場合は,JavaVMによってFullGCが実行されます。
New領域で使用されているメモリのサイズ>Tenured領域の空き領域のサイズ |
式が示すとおり,Tenured領域の空き領域のサイズが小さくなるとFullGCが発生します。Tenured領域の空き領域は,CopyGCが発生したときにSurvivor領域から移動(昇格)するJavaオブジェクトによって使用されます。つまり,昇格するJavaオブジェクトを削減できれば,FullGCの発生を抑えられます。なお,何回かのCopyGCの実行で削除されないで,昇格の対象になるオブジェクトを長寿命オブジェクトといいます。
長寿命オブジェクトには大きく分けて2種類あります。一つは,FullGCで回収されないオブジェクトです。例えばアプリケーションの実行中は常に生存し続けるような,本来Tenured領域に格納される必要があるオブジェクトが当てはまります。このようなオブジェクトは増加し続けることはないため,FullGCが発生する本質的な原因ではありません。このような長寿命オブジェクトの影響を排除したい場合は,Tenured領域のサイズを増加することで対処できます。
二つ目は,FullGCで回収されるオブジェクトです。FullGCで回収される長寿命オブジェクトとは,Tenured領域に昇格する程度に長寿命であるが,一定期間で不要となるオブジェクトを指します。このような長寿命オブジェクトはFullGCの発生までは増加し続けるため,FullGC発生の原因となります。
FullGCで回収されるオブジェクト,およびFullGCで回収されないオブジェクトについて,次の図で説明します。
図8-1 FullGCで回収されるオブジェクト,およびFullGCで回収されないオブジェクト
一定期間で不要となるオブジェクトの増加を防ぐ対策として,Tenured領域のサイズを増加しただけでは,効果がありません。Tenured領域のサイズを2倍にしても,FullGCの発生間隔が2倍になるだけで,期待するほどの効果は得られません。
つまり,FullGCの発生を抑止するためには,一定期間で不要となるオブジェクトのTenured領域への昇格を減らすことがポイントとなります。
アプリケーションサーバでは,一部のJavaオブジェクトについて,CopyGC発生時の昇格先がExplicitヒープになるように設定されています。明示管理ヒープ機能を使用していない場合の昇格と明示管理ヒープ機能を使用している場合の昇格の違いを次の図に示します。
図8-2 明示管理ヒープ機能を使用していない場合の昇格と明示管理ヒープ機能を使用している場合の昇格の違い
図の1.のタイミングでは,どちらの場合も同じ状態です。2.のオブジェクトが昇格するタイミングで,明示管理ヒープ機能を使用していない場合の昇格では,すべての長寿命オブジェクトがTenured領域に移動します。一方,明示管理ヒープ機能を使用している場合,長寿命オブジェクトのうち,一定期間後に破棄されることがわかっているオブジェクトについてはExplicitヒープに移動します。これによって,Tenured領域に移動するのは,破棄される予定がない長寿命オブジェクトに限定され,Tenured領域の使用済みサイズの増加が緩やかになります。なお,3.で示すとおり,明示管理ヒープ機能を使用している場合のExplicitヒープのオブジェクトは,不要になったタイミングで削除されます。
対象となるJavaオブジェクトについては,「8.4 J2EEサーバ利用時にExplicitヒープに配置されるオブジェクト」を参照してください。また,GCのアルゴリズムについては,マニュアル「アプリケーションサーバ システム設計ガイド」の「7. JavaVMのメモリチューニング」を参照してください。
なお,ユーザが開発するアプリケーションで明示管理ヒープ機能を使用する場合は,一定期間後に破棄される長寿命オブジェクトを,直接Explicitヒープに生成します。これによって,Tenured領域のメモリサイズ増加を防ぎます。Explicitヒープに生成できるJavaオブジェクトについては,「8.5 アプリケーションで任意にExplicitヒープに配置できるオブジェクト」を参照してください。
明示管理ヒープ機能は,JavaVMの機能です。明示管理ヒープ機能を利用する方法には,次の2種類があります。
明示管理ヒープ機能の位置づけを次の図に示します。なお,図中のJavaVMログファイル出力機能は,JavaVMログファイル出力機能のことです。
図8-3 明示管理ヒープ機能の位置づけ
明示管理ヒープ機能の範囲である,明示管理ヒープ機能API,自動配置設定ファイル,明示管理ヒープ機能適用除外設定/適用除外無効設定ファイル,明示管理ヒープ機能を構成する各機能,Tenured領域内不要オブジェクト統計機能,およびExplicitヒープについて説明します。
明示管理ヒープ機能で管理するExplicitヒープは,Javaヒープ外の領域です。Explicitヒープを使用する場合,使用しない場合に比べて,メモリの使用量が増加します。
明示管理ヒープ機能を使用する場合は,必要なメモリサイズとしてExplicitヒープの最大サイズを見積もり,適切に設定する必要があります。明示管理ヒープ機能を利用する流れ,Explicitヒープに格納するオブジェクト(Tenured領域のメモリサイズ増加の要因になるオブジェクト),およびExplicitヒープのサイズの見積もりについては,マニュアル「アプリケーションサーバ システム設計ガイド」の「7.11 Explicitヒープのチューニング」を参照してください。