Javaヒープのチューニング方法および、チューニングによる影響範囲を説明します。
チューニング方法
Javaヒープの各領域のサイズは、“表9.3 Javaヒープに関するオプション”に示すオプションをJava起動時に指定することで設定ができます。
メモリ割り当てプールのデフォルトの初期値および最大値を、“表9.4 メモリ割り当てプールのデフォルトのサイズ”に示します。
また、Permanent世代領域のデフォルトの初期値および最大値を、“表9.5 Permanent世代領域のデフォルトのサイズ”に示します。
また各オプションにおいて、“表9.3 Javaヒープに関するオプション”中に記載されていないデフォルト値を、“表9.6 Javaヒープに関するオプション(-XX:NewSize/-XX:NewRatio)のデフォルト値”に示します。
オプション | オプションの機能 (注1) |
---|---|
-Xms | メモリ割り当てプールの初期値を指定します。 なお、指定値が1MB未満の場合、または-XX:NewSizeオプションの値(デフォルト値を含む)以下の場合、初期化エラーとなり、Javaプロセスは終了します。 |
-Xmx | メモリ割り当てプールの最大値を指定します。 なお、指定値(または調整値)が、-Xmsオプションで指定された値よりも小さな値の場合、初期化エラーとなり、Javaプロセスは終了します。 |
-XX:NewSize | New世代領域のヒープサイズを指定します。
なお、指定値がJava VMとしての下限値未満の場合、初期化エラーとなり、Javaプロセスは終了します。そのため、本オプションを指定する場合は、1MB以上の値を指定してください。 |
-XX:MaxNewSize | New世代領域の最大ヒープサイズを設定します。
なお、指定値が、-XX:NewSizeオプションで指定された値よりも小さな値の場合は、-XX:NewSizeオプションで指定された値となります。 |
-XX:NewRatio (注3) | New世代領域とOld世代領域のサイズ比率を指定します。 |
-XX:SurvivorRatio (注2)(注4) | New世代領域を構成するEden領域とSurvivor領域のサイズ比率を指定します。 |
-XX:TargetSurvivorRatio (注2)(注4) | ガーベジコレクション(GC)処理後の生存オブジェクトがSurvivor領域を占める割合を、指定したパーセンテージ値に調整します。 |
-XX:PermSize | Permanent世代領域の初期値を指定します。 なお、指定値が1MB未満の場合は初期化エラーとなり、Javaプロセスは終了します。 |
-XX:MaxPermSize | Permanent世代領域の最大値を指定します。 なお、指定値(または調整値)が、-XX:PermSizeオプションで指定された値よりも小さな値の場合は、-XX:PermSizeオプションで指定された値となります。 |
サイズを指定するオプションでは単位として次の文字を指定できます。
KB(キロバイト)を指定する場合: “k”または“K”
MB(メガバイト)を指定する場合: “m”または“M”
GB(ギガバイト)を指定する場合: “g”または“G”
パラレルGCを使用する場合、このオプションへの指定値は無効となります。
CMS付きパラレルGCを使用する場合、このオプションへの指定値は無効となります。
CMS付きパラレルGCを使用する場合、かつ-XX:UseFJcmsGC=type0またはtype0p指定でない場合、このオプションへの指定値は無効となります。
OS | JDK/JREの実行モード | GC処理 | 初期値 | 最大値 |
---|---|---|---|---|
Windows | 32ビットモード | シリアルGC | 5.0MB | 96MB |
パラレルGC (注1) | 7.5MB | |||
CMS付きパラレルGC | (注2) | |||
Windows Server(R) x64 Editions | 64ビットモード | シリアルGC | 6.4375MB | 126MB |
パラレルGC (注1) | 8.5MB | |||
CMS付きパラレルGC | (注2) | |||
Linux for x86 Linux for Intel64 | 32ビットモード | シリアルGC | 5.0MB | 96MB |
パラレルGC (注1) | 7.5MB | |||
CMS付きパラレルGC | (注2) | |||
Linux for Intel64 | 64ビットモード | シリアルGC | 6.4375MB | 126MB |
パラレルGC (注1) | 8.5MB | |||
CMS付きパラレルGC | (注2) | |||
Solaris | 64ビットモード | シリアルGC | 6.4375MB | 128MB |
パラレルGC (注1) | 12.0MB | |||
CMS付きパラレルGC | (注2) |
デフォルトで使用されるGC処理です。
メモリ割り当てプールの最大値が64MB未満の場合は、メモリ割り当てプールの最大値と等しくなります。メモリ割り当てプールの最大値が64MB以上の場合は、64MBとなります。
OS | JDK/JREの実行モード | Java VM | 初期値 | 最大値 |
---|---|---|---|---|
Windows Linux for Intel64 | 32ビットモード | Java HotSpot Client VM | 12MB | 64MB |
FJVM (注1) | 16MB | |||
Windows Server(R) x64 Editions | 64ビットモード | FJVM (注1) | 20.75MB | 84MB |
Solaris | 64ビットモード | FJVM (注1) | 20.75MB | 84MB |
デフォルトで使用されるJava VMです。
GC処理にパラレルGCを使用している場合は、24MBになります。シリアルGC または CMS付きパラレルGCを使用している場合は、20.75MB になります。
OS | JDK/JREの実行モード | Java VM | -XX:NewSize | -XX:NewRatio |
---|---|---|---|---|
Windows Linux for Intel64 | 32ビットモード | Java HotSpot Client VM | 1024KB | 2 |
FJVM (注1) | ||||
Windows Server(R) x64 Editions | 64ビットモード | FJVM (注1) | 1280KB | |
Solaris | 64ビットモード | FJVM (注1) | 1280KB |
デフォルトで使用されるJava VMです。
チューニングの方針
Javaヒープをチューニングする際、次の方針があります。
FullGCを実行したにもかかわらず、メモリ不足が発生する場合、GCのログを採取し、メモリ割り当てプールまたはPermanent世代領域のどちらかの領域が不足しているかどうかを確認します。
FullGCはコストがかかります。このため、メモリ不足が発生しなくても、Javaアプリケーションがハングアップしたかのように一時的に無反応になる場合、FullGCの影響を受けている場合があります。GCのログを採取し、Javaヒープが必要以上に大きなサイズになっていれば、Javaヒープのサイズを縮小する方針でチューニングします。
効率的なNew GCに対して、FullGCはコストがかかります。このため、New世代領域とOld世代領域のサイズのバランスを考慮する必要があります。なお、GC処理としてパラレルGCを使用する場合は、JavaヒープのNew世代領域およびOld世代領域の大きさに関する値が自動的に調整および最適化されるため、通常はこのバランスを考慮する必要はありません。
仮想メモリに余裕がある場合は、Javaプロセスを複数起動して、プロセス多重度を上げる方法を検討します。プロセス多重度を上げることにより、プロセスごとのユーザ空間を有効に使うことが可能になります。ただし、メモリのスワッピングによるスローダウンに注意する必要があります。
チューニングの影響範囲
メモリ割り当てプールの大きさ(-Xmxオプションの指定値)や、New世代領域とOld世代領域の大きさのバランスを変更した場合の影響範囲を、次に示します。
メモリ割り当てプールの大きさを縮小した場合、GCが頻発することがあります。
メモリ割り当てプールの大きさを拡張した場合、FullGCに時間がかかることがあります。
メモリ割り当てプールの大きさを拡張した場合、その分ユーザ空間や仮想メモリが少なくなるため、スタックやネイティブモジュールの動作に必要な領域を確保できず、メモリ不足になることがあります。
New世代領域の大きさがメモリ割り当てプールの大きさの半分となるようなチューニングを行った場合、一般的に、FullGCが発生しやすくなる傾向があります。なお、Javaアプリケーション実行時のオブジェクト生成/解放などの特性に依存しますので、どのアプリケーションの場合でもFullGCが発生しやすいというわけではありません。
注意
overcommit memory機能が有効な場合の注意事項
「overcommit memory機能」が有効な場合、Linuxは、Javaヒープの各領域の最大値に相当する仮想メモリ資源を、Java VMの起動時に、Javaプロセスに対して予約します。
このため、-Xms値と-Xmx値を異なる値にしてJavaプロセスを起動する場合、本機能の有効/無効によって、Javaプロセス起動時にJavaヒープとして必要となる仮想メモリの量が異なります。
overcommit memory機能が無効、またはovercommit memory機能がないシステムの場合
Javaヒープ用仮想メモリ量 = 「-Xms値」 + 「Perm域初期値」
overcommit memory機能が有効なシステムの場合
Javaヒープ用仮想メモリ量 = 「-Xmx値」 + 「-XX:MaxPermSize値」
この結果、仮に同量の仮想メモリ資源を持つシステムの場合であっても、本機能の有効/無効によって、同時に起動できるJavaプロセスの数が異なる場合があります。
Linuxで仮想メモリ資源の見積もりを行う場合には、overcommit memory機能の有無に注意してください。