OutOfMemoryErrorがスローされた場合、考えられる原因とその対処方法を説明します。
想定される原因(メモリリーク)
VMがガーベジコレクションを繰り返しても、時間の経緯とともにメモリ消費量が増大していく場合、プログラム中メモリリークを起こしている可能性があります。
メモリリークの結果、Javaのヒープ不足が発生しOutOfMemoryErrorがスローされる場合があります。
この場合、ガーベジコレクションのログを採取して、Javaヒープの消費状況を確認してください。ガーベジコレクションのログを採取する方法は、“7.4.6 ガーベジコレクションのログ出力”を参照してください。
想定される原因(Javaヒープ不足)
通常、OutOfMemoryErrorは、Javaヒープ不足が原因でスローされます。
ガーベジコレクションのログを採取して、Javaヒープの消費状況を確認してください。
Javaヒープの空き容量がないことが確認されたら、Javaヒープをチューニングしてください。
ガーベジコレクションのログを採取する方法は、“7.4.6 ガーベジコレクションのログ出力”を参照してください。
Javaヒープのチューニング方法は、“7.5.1 Javaヒープおよびメタスペースのチューニング”を参照してください。
想定される原因(メタスペース不足)
メタスペースが不足によって、OutOfMemoryErrorがスローされる場合があります。
ガーベジコレクションのログを採取して、メタスペースの消費状況を確認してください。
メタスペースの空き容量がないことが確認されたら、メタスペースをチューニングしてください。
ガーベジコレクションのログを採取する方法は、“7.4.6 ガーベジコレクションのログ出力”を参照してください。
メタスペースのチューニング方法は、“7.5.1 Javaヒープおよびメタスペースのチューニング”を参照してください。
注意
メタスペースは、クラスローダーごとに管理するため、あるクラスローダーでロードされたクラス情報を、別のクラスローダーが管理するメタスペースに格納できません。
また、各クラスローダーのメタスペースは、クラス情報ごとに取得するのではなく、ある程度のまとまったサイズごとに取得して、そこにクラス情報を設定していきます。
このため、取得済みのメタスペースに空きがある場合でも、別のクラスローダーが管理するものであれば、その空きを使用できません(使用済みと扱います)。
その結果、使用済みのサイズが“-XX:MaxMetaspaceSize”オプションで指定した値に到達していないにも関わらず、OutOfMemoryErrorがスローされる場合があります。
想定される原因(ユーザ空間不足)
多量のスレッドを生成すると、ユーザ空間に多量のスタックが割り当てられます。
これによりユーザ空間が不足すると、OutOfMemoryErrorがスローされるか、エラーメッセージとして表示されます。その後、プロセスが終了します。
java.lang.OutOfMemoryError: unable to create new native thread |
また、JavaヒープやOSの仮想メモリに余裕があるにもかかわらず、ユーザ空間内にメモリを確保できなかった場合のメッセージについては、“7.2.4 メモリー領域が確保できずにJavaVMが終了した場合のメッセージ出力機能”を参照してください。
ユーザ空間が不足している場合は、Javaヒープまたはスタックのサイズを小さくするなどのチューニングを行ってください。
スタックのサイズをチューニングする方法は、“7.5.2 スタックのチューニング”を参照してください。
Javaヒープおよびメタスペースのチューニング方法は、“7.5.1 Javaヒープおよびメタスペースのチューニング”を参照してください。
なお、仮想メモリに余裕がある場合は、Javaプロセスを複数起動して、プロセス多重度を上げる方法もあります。GlassFishアプリケーションの場合、GlassFishのチューニングを行ってください。
想定される原因(仮想メモリ不足)
仮想メモリが不足してスレッドが生成できない場合、以下のOutOfMemoryErrorがスローされるか、エラーメッセージとして表示されます。その後、プロセスが終了します。
java.lang.OutOfMemoryError: unable to create new native thread |
また、OSの仮想メモリが不足した場合のメッセージについては、“7.2.4 メモリー領域が確保できずにJavaVMが終了した場合のメッセージ出力機能”を参照してください。
仮想メモリが不足した場合は、他の不要なプロセスを終了して仮想メモリに余裕を持たせるか、物理メモリ(RAM)またはスワップファイルを拡張して仮想メモリを増やすようにチューニングを行ってください。
想定される原因(ガーベジコレクション処理の実行抑止)
ガーベジコレクション処理(GC処理)の実行抑止により、クリティカルセクション状態時にOutOfMemoryErrorがスローされた場合は、必要に応じて、GC処理の実行抑止による影響ができるだけ小さくなるように、実行するアプリケーションの処理内容を見直してください(アプリケーション処理内の、GC処理の実行抑止に関係する機能の利用見直しを行ってください)。
GC処理の実行抑止については、“7.4.1 ガーベジコレクション処理”を参照してください。
なお、Javaヒープのチューニングにより、GC処理の実行抑止によるOutOfMemoryErrorの発生が緩和できる場合があります。
クリティカルセクション状態時に、ネイティブプログラムからJNIを利用してJavaのオブジェクトの生成要求を行っていないアプリケーションの場合は、Old世代領域を大きくする(メモリ割り当てプール全体を大きくする)チューニングで、GC処理の実行抑止によるOutOfMemoryErrorの発生が緩和できる場合があります。
クリティカルセクション状態時に、ネイティブプログラムからJNIを利用してJavaのオブジェクトの生成要求を行っているアプリケーションの場合は、New世代領域を大きくするチューニングで、GC処理の実行抑止によるOutOfMemoryErrorの発生が緩和できる場合があります。
ガーベジコレクションのログを採取する方法は、“7.4.6 ガーベジコレクションのログ出力”を参照してください。
Javaヒープおよびメタスペースのチューニング方法は、“7.5.1 Javaヒープおよびメタスペースのチューニング”を参照してください。
注意
PCMI1105メッセージが出力されている場合は、GlassFish Serverのコンテナ情報ログ(info.log)およびGlassFish Serverのログ(console.log)に出力される「Java VMのヒープ域不足の詳細情報」を参照して判断してください。