Java
Z
信頼度ランク
| S | 公式ソース確認済み |
| A | 成功実績多数・失敗例少数 |
| B | 賛否両論 |
| C | 動作未確認・セキュリティリスク高 |
| Z | 個人所感 |
JavaのOutOfMemoryErrorを完全に解決する方法
java.lang.OutOfMemoryErrorの種類ごとの原因と対処法を解説します。ヒープ、Metaspace、スタックの問題を網羅。
一言結論
OOMEはエラーメッセージの種類(heap space / Metaspace / GC overhead)によって原因が異なり、ヒープダンプ(-XX:+HeapDumpOnOutOfMemoryError)を取得してVisualVMで解析するのが確実な診断手順だ。
OutOfMemoryError の種類
OutOfMemoryError は一種類ではありません。スタックトレースのメッセージで原因が分かれます。
1. Java heap space
java.lang.OutOfMemoryError: Java heap space
原因: ヒープ領域が足りない。大量のオブジェクト生成やメモリリークが主因。
対処法①: JVMオプションでヒープを増やす
java -Xms512m -Xmx2g -jar myapp.jar
# -Xms: 初期ヒープサイズ
# -Xmx: 最大ヒープサイズ
Eclipse での設定: Run > Run Configurations > Arguments > VM arguments
対処法②: メモリリークを探す
// よくあるメモリリークパターン
static List<String> cache = new ArrayList<>();
void addData(String data) {
cache.add(data); // 削除しないと無限に増え続ける
}
2. GC overhead limit exceeded
java.lang.OutOfMemoryError: GC overhead limit exceeded
原因: GCが全体の98%以上の時間を費やしているが、ほとんどメモリを回収できていない状態。
対処法:
# ヒープを増やしつつGCログを出力
java -Xmx4g -Xlog:gc*:file=gc.log -jar myapp.jar
GCログを解析して不要なオブジェクトの保持を特定します。
3. Metaspace
java.lang.OutOfMemoryError: Metaspace
原因: クラスのメタ情報を格納するMetaspaceが枯渇。動的クラスロード(JSP、Groovyなど)が原因になりやすい。
対処法:
java -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -jar myapp.jar
4. unable to create new native thread
java.lang.OutOfMemoryError: unable to create new native thread
原因: OS が新しいスレッドを作れない(スレッドが枯渇している)。
対処法:
# Linux でのスレッド数上限確認
ulimit -u
# スレッドプールのサイズを見直す
// スレッドを無制限に作るアンチパターン
for (int i = 0; i < tasks.size(); i++) {
new Thread(() -> process()).start(); // 危険
}
// ExecutorService で管理する
ExecutorService pool = Executors.newFixedThreadPool(10);
tasks.forEach(t -> pool.submit(() -> process(t)));
ヒープダンプで根本原因を特定する
# 起動時オプション: OOM発生時に自動ダンプ
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/tmp/heap.hprof -jar myapp.jar
# 実行中プロセスからダンプ取得
jmap -dump:format=b,file=/tmp/heap.hprof <PID>
ダンプは Eclipse Memory Analyzer (MAT) で解析できます。
Eclipse での確認手順
Window > Preferences > Java > Installed JREsでJDKを確認- プロジェクト右クリック →
Run As > Run Configurations ArgumentsタブのVM argumentsに-Xmx2gを追加
まとめ
| エラーメッセージ | 主な原因 | まず試すこと |
|---|---|---|
| Java heap space | ヒープ不足 / リーク | -Xmx を増やす |
| GC overhead | ほぼメモリ満杯 | ヒープ増量 + GCログ確認 |
| Metaspace | クラスロード過多 | -XX:MaxMetaspaceSize 設定 |
| native thread | スレッドが多すぎる | スレッドプール見直し |