SJ blog
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 での確認手順

  1. Window > Preferences > Java > Installed JREs でJDKを確認
  2. プロジェクト右クリック → Run As > Run Configurations
  3. Arguments タブの VM arguments-Xmx2g を追加

まとめ

エラーメッセージ主な原因まず試すこと
Java heap spaceヒープ不足 / リーク-Xmx を増やす
GC overheadほぼメモリ満杯ヒープ増量 + GCログ確認
Metaspaceクラスロード過多-XX:MaxMetaspaceSize 設定
native threadスレッドが多すぎるスレッドプール見直し