7.2.6 SerialGC使用時のJavaVMで使用するメモリ空間の構成とJavaVMオプション
ここでは,SerialGC使用時のJavaVMで使用するメモリ空間の構成と,JavaVMオプションについて説明します。
JavaVMでは,JavaVM固有領域とOS固有領域という,2種類のメモリ空間を使用します。
JavaVMで使用するメモリ空間の構成を次の図に示します。なお,図中の番号は,表7-2の項番と対応しています。
それぞれの領域について説明します。なお,Eden領域,Survivor領域,およびTenured領域を合わせた領域を,Javaヒープといいます。
- Eden領域
-
newによって作成されたJavaオブジェクトが最初に格納される領域です。
- Survivor領域
-
New領域に格納されていたJavaオブジェクトのうち,CopyGC実行時に破棄されなかったJavaオブジェクトが格納される領域です。Survivor領域は,From空間とTo空間で構成されます。From空間とTo空間のサイズは同じです。
- Tenured領域
-
長期間必要であると判断されたJavaオブジェクトが格納される領域です。Survivor領域で指定回数を超えてCopyGCの実行対象となり,破棄されなかったJavaオブジェクトが,この領域に移動されます。
- Metaspace領域
-
ロードされたclassなどの情報が格納される領域です。
ただし,圧縮オブジェクトポインタ機能が有効な場合,Metaspace領域内にCompressed Class Spaceという領域が作成されます。この領域に,Javaヒープ内のオブジェクトから参照されるクラス情報が配置されます。そして,それ以外のメソッド情報などがCompressed Class Space以外のMetaspace領域に配置されます。圧縮オブジェクトポインタ機能については,マニュアル「アプリケーションサーバ 機能解説 保守/移行編」の「9.18 圧縮オブジェクトポインタ機能」を参照してください。
- Explicitヒープ領域
-
FullGCの対象外になるJavaオブジェクトが格納される領域です。Explicitヒープ領域はJavaVM独自のメモリ空間で,明示管理ヒープ機能を利用する場合だけ確保されます。
- Cヒープ領域
-
JavaVM自身が使用する領域です。JNIで呼び出されたネイティブライブラリでも使用されます。
- 参考
-
Cヒープ領域の最大サイズについて(AIXの場合)
AIXの場合,JNIを使用してJavaVMを起動するプログラムを実行するときは,次のどれかの方法でCヒープ領域の最大サイズを設定してください。どれも設定していない場合は,シェルのdatasizeリソースのデフォルト値がCヒープ領域の最大サイズとなります。
-
シェルでdatasizeリソースの値にCヒープ領域のサイズを指定してから,プログラムを実行してください。
csh(Cシェル)の場合:limit datasize <Cヒープ領域のサイズ>
sh(標準シェル)およびkshの場合:ulimit -d <Cヒープ領域のサイズ>
-
プログラム生成時のリンケージオプションに,「-bmaxdata:<Cヒープ領域のサイズ>」を指定してください。
-
環境変数LDR_CNTRLでMAXDATA値を指定してから,プログラムを実行してください。
csh(Cシェル)の場合:setenv LDR_CNTRL MAXDATA=<Cヒープ領域のサイズ>
sh(標準シェル)およびkshの場合:export LDR_CNTRL=MAXDATA=<Cヒープ領域のサイズ>
-
setrlimit()システムコールを使用して,Cヒープ領域のサイズを設定する処理をプログラム内で実装してください。
-
例えば,次のような領域があります。
- コードキャッシュ領域
-
JITコンパイルによって生成されたJITコンパイルコードが格納される領域です。
JavaVMは,呼び出し回数やループ回数が多いJavaメソッドをJITコンパイルして実行することで,処理の高速化を行います。
- 参考
-
コードキャッシュ領域の最大サイズについて
コードキャッシュ領域の最大サイズは,ReservedCodeCacheSizeオプションに指定します。
ReservedCodeCacheSizeオプションには,デフォルト値以上の値を指定してください。デフォルト値については,マニュアル「アプリケーションサーバ リファレンス 定義編(サーバ定義)」の「14.4 Application Serverで指定できるJava HotSpot VMのオプションのデフォルト値」を参照してください。
また,コードキャッシュ領域が枯渇していた場合,または枯渇するおそれがある場合は,コードキャッシュ領域の拡張を検討してください。
コードキャッシュ領域を拡張する場合は,次の点に注意してください。
-
JITコンパイルコードのサイズは計算で見積もることができません。そのため,Javaアプリケーション実行環境でコードキャッシュ領域の使用量を実測し,システムが使用するコードキャッシュ領域(最大2メガバイト)の使用量を考慮した上で,コードキャッシュ領域の最大サイズを見積もってください。
-
仮想メモリの使用量の見積もりについては,「5.3 プロセスごとに使用するメモリの見積もり」または「6.3 仮想メモリの使用量の見積もり」を参照してください。
-
- スタック領域
-
Javaスレッドのスタック領域です。
- 参考
-
メインスレッドのスタック領域サイズについて
メインスレッドのスタック領域サイズを変更する場合は,-Xssに指定した値以上の値を設定してください。-Xssオプションでは,メインスレッドのスタック領域サイズは変更できません。J2EEサーバ起動時のJ2EEアプリケーションの自動開始処理はメインスレッドで行うため,自動開始に失敗する場合があります。この場合,J2EEアプリケーションの自動開始を行わないように,-nostartappオプションを指定してJ2EEサーバを起動後,手動でJ2EEアプリケーションを起動するか,Managementアクションを使用してJ2EEアプリケーションを起動してください。
それぞれの領域のサイズや割合などを指定するJavaVMオプションを次の表に示します。なお,表の項番は,図7-7と対応しています。
項番 |
オプション名 |
オプションの意味 |
---|---|---|
1 |
-Xmx<size> |
Javaヒープの最大サイズを設定します。 |
2 |
-Xms<size> |
Javaヒープの初期サイズを設定します。 |
3 |
-XX:MaxMetaspaceSize=<size> |
Metaspace領域の最大サイズを設定します。 |
4 |
-XX:MetaspaceSize=<size> |
Metaspace領域の初期サイズを設定します。 |
5 |
-Xmn<size> |
New領域の初期値および最大値を設定します。 |
6 |
-XX:[+|-]HitachiAutoExplicitMemory |
自動配置機能を使用する場合に,JavaVMを起動したタイミングでExplicitメモリブロックで使用するメモリを確保します。※ |
7 |
-XX:HitachiExplicitHeapMaxSize=<size> |
Explicitヒープ領域サイズの最大サイズを設定します。※ |
8 |
-Xss<size> |
1スタック領域の最大サイズを設定します。 |
9 |
-XX:ReservedCodeCacheSize=<size> |
JavaVMが使用する領域のうち,コードキャッシュ領域の最大サイズを設定します。 |
10 |
-XX:NewRatio=<value> |
New領域に対するTenured領域の割合を設定します。 <value>が2の場合は,New領域とTenured領域の割合が,1:2になります。 |
11 |
-XX:SurvivorRatio=<value> |
Survivor領域のFrom空間とTo空間に対するEden領域の割合を設定します。 <value>に8を設定した場合は,Eden領域,From空間,To空間の割合が,8:1:1になります。 |
12 |
-XX:TargetSurvivorRatio=<value> |
CopyGC実行後のSurvivor領域内でJavaオブジェクトが占める割合の目標値を設定します。 |
13 |
-XX:MaxTenuringThreshold=<value> |
CopyGC実行時に,From空間とTo空間でJavaオブジェクトを入れ替える回数の最大値を設定します。 設定した回数を超えて入れ替え対象になったJavaオブジェクトは,Tenured領域に移動されます。 |
注※ 明示管理ヒープ機能を使用するための前提オプションが有効になっている必要があります。詳細は「7.11 Explicitヒープのチューニング」を参照してください。
- 参考
-
-
JavaVMオプションの設定の仕方
JavaVMオプションは,次の個所に設定します。
表7‒3 JavaVMオプションを設定する個所 対象
設定方法
設定個所
J2EEサーバ
Smart Composer機能
- 定義ファイル
-
簡易構築定義ファイル
- 設定対象
-
論理J2EEサーバ(j2ee-server)
- パラメタ名
-
add.jvm.arg
バッチサーバ
Smart Composer機能
- 定義ファイル
-
簡易構築定義ファイル
- 設定対象
-
論理J2EEサーバ(j2ee-server)
- パラメタ名
-
add.jvm.arg
EJBクライアントアプリケーション
ファイル編集
- 定義ファイル
-
usrconf.cfg※
- パラメタ名
-
add.jvm.argキー
-
- ポイント
-
それぞれのオプションのデフォルト値は,OSによって異なります。オプションのデフォルト値については,マニュアル「アプリケーションサーバ リファレンス 定義編(サーバ定義)」の「14.4 Application Serverで指定できるJava HotSpot VMのオプションのデフォルト値」を参照してください。
- 注意事項
-
Javaヒープ領域,Metaspace領域,Compressed Class Space,Cヒープ領域のどれかが不足するとOutOfMemoryが発生し,メモリ不足が解消されないかぎり正常に稼働できない状態が長く続くことになります。
これに対して,OutOfMemory発生時のシステムへの影響を小さくするために,次のオプションを使用できます。
-
-XX:+HitachiOutOfMemoryAbort(OutOfMemory発生時強制終了機能)
-
-XX:+HitachiOutOfMemoryHandling(OutOfMemoryハンドリング機能)
OutOfMemory発生時強制終了機能は,Javaヒープ不足やMetaspace領域不足,Compressed Class Space不足などが原因でOutOfMemoryが発生した場合に,J2EEサーバを強制終了するための機能です。Javaヒープ領域,Metaspace領域,Compressed Class Space,Cヒープ領域のメモリ不足によってOutOfMemoryが発生したときに,J2EEサーバを強制終了して,J2EEサーバを自動再起動します。これによって,J2EEサーバを正常に稼働できる状態に早期に回復できます。
OutOfMemoryハンドリング機能は,OutOfMemory発生時強制終了機能を前提とする機能です。OutOfMemory発生時強制終了機能を使用している場合でも,特定の条件に合致するときに限ってJ2EEサーバの実行を継続したい場合に使用します。
リクエスト処理でオブジェクトを大量に確保しようとした場合,巨大なオブジェクトを確保しようとした場合などにJavaヒープ不足が原因のOutOfMemoryが発生したときに,J2EEサーバの実行を継続するようにしたいときには,OutOfMemoryハンドリング機能を使用してください。
オプションの詳細については,マニュアル「アプリケーションサーバ リファレンス 定義編(サーバ定義)」の「-XX:[+|-]HitachiOutOfMemoryAbort(強制終了オプション)」および「-XX:[+|-]HitachiOutOfMemoryHandling(OutOfMemoryハンドリングオプション)」を参照してください。
-
Metaspace領域の特殊なチューニングの考え方
Metaspace領域の特性を活用したチューニングについて記載します。JDK7までのPermanent領域はオプションで設定した値のメモリを必ず使用していましたが,Metaspace領域はオプションに設定された値のメモリを必ず使用するわけではありません。実際には,実行に必要なサイズのメモリしか使用しません。
(a) Metaspace領域のOutOfMemoryErrorの発生リスクを下げる
見積もり時に想定していなかったMetaspace領域の使用量の増加によって,OutOfMemoryErrorが発生するリスクを下げるためには,見積もり値にバッファを持たせた値を-XX:MaxMetaspaceSizeと-XX:CompressedClassSpaceSizeに設定してください。Metaspace領域の使用量がこの値を超えるまではMetaspace領域のOutOfMemoryErrorは発生しません。
(b) Metaspace領域に起因するFullGCの発生リスクを下げる
見積もり時に想定していなかったMetaspace領域の使用量の増加によって,Metaspace領域に起因するFullGCが発生するリスクを下げるためには,見積もり値にバッファを持たせた値を-XX:MetaspaceSize,-XX:MaxMetaspaceSize,-XX:CompressedClassSpaceSizeに設定してください。Metaspace領域の使用量がこの値を超えるまではMetaspace領域に起因するFullGCは発生しません。
-