「Swapは十分にあるのに、なぜかJavaプロセスがOOMで落ちる」
この現象は、Java × Linux 障害対応で非常によくある誤解です。
結論から言うと、
Swapがある=JavaがOOMにならない、ではありません。
本記事では、
- SwapがあってもJavaがOOMになる理由
- OSとJVMのメモリ管理の違い
- 実務での正しい確認ポイントと対処策
を整理して解説します。
目次
まず結論:JavaはSwapを前提に動いていない
Linuxでは、
- 物理メモリ(RAM)
- Swap
を合わせて「利用可能メモリ」と見なしますが、 JVMはこの考え方を基本的に採用していません。
Javaは「物理メモリ前提」でヒープを確保します。
誤解① SwapがあればOOM Killerは発動しない
これは誤りです。
理由
- LinuxのOOM KillerはSwap残量だけで判断しない
- メモリ割当失敗やフラグメンテーションも考慮
そのため、
- Swapが空いている
- しかしRAMが逼迫している
という状況でも、OOM Killerは発動します。
確認コマンド
free -h
誤解② Javaは必要に応じてSwapを使ってくれる
これも誤りです。
理由
Javaは以下の領域を常駐メモリ(RSS)として使用します。
- Java Heap
- Metaspace
- Thread Stack
- Direct Memory
これらはSwapに追い出されると致命的な性能劣化を起こすため、 Linuxカーネルは積極的にSwapアウトしません。
典型パターン① ヒープサイズが物理メモリ限界まで指定されている
例
- 物理メモリ:8GB
- Swap:8GB
- Java起動オプション:-Xmx8g
→ ほぼ確実にOOM Killer対象
なぜか
- OS自身の使用メモリ
- ヒープ外メモリ
を考慮していないためです。
対処
-Xms4g -Xmx4g
目安:Xmxは物理メモリの60〜70%
典型パターン② Direct MemoryがSwapに逃げない
Netty・NIO・Kafka Clientなどは Direct Memory(ヒープ外)を多用します。
この領域は、
- ヒープサイズに含まれない
- Swapに逃げにくい
ため、物理メモリを圧迫します。
確認
jcmd <PID> VM.native_memory summary
対処
-XX:MaxDirectMemorySize=512m
典型パターン③ systemd / cgroup によるメモリ制限
systemd管理のJavaサービスでは、 Swapがあってもメモリ制限によりOOMになることがあります。
確認
systemctl show <service> | grep Memory
例
MemoryMax=2G
→ この制限を超えた時点でOOM
典型パターン④ vm.swappiness の誤解
「swappinessを上げればJavaはSwapを使う」と思われがちですが、 これは限定的な効果しかありません。
確認
cat /proc/sys/vm/swappiness
注意点
- Javaの主要メモリはSwap対象になりにくい
- 無理にSwapさせるとGCやレスポンスが崩壊
OOM Killerが発動しているかの確認
Javaログに何も残らずプロセスが消える場合は、 OS側OOMを疑います。
確認
dmesg | grep -i oom
実務での正しい考え方
- Swapは「最後の保険」でしかない
- JavaはSwap前提で設計してはいけない
- 物理メモリ内で完結する設計が必須
おすすめ設計指針
- Xmxは物理メモリの60〜70%
- Direct Memory / Metaspace を明示制限
- systemd / cgroup の制限確認
- SwapはOOM回避ではなくOS安定用
まとめ
- SwapがあってもJavaは普通にOOMで落ちる
- JVMは物理メモリ前提で動く
- ヒープ外メモリが原因のケースが多い
- OOMは「Swap不足」ではなく「設計ミス」
Swapに期待せず、 JavaとLinuxのメモリ設計を正しく理解することが 安定運用への近道です。
あわせて読みたい


OOM Killer詳細|Linuxメモリ枯渇時の挙動・調査・対処を完全解説
Linuxサーバーで突然プロセスが落ちる/サーバーが不安定になる原因として非常に多いのが OOM Killer(Out Of Memory Killer)です。 本記事では、OOM Killerの仕組み・…
あわせて読みたい


LinuxのOOM Killerが発動する条件と回避策【実務での完全理解】
Linuxを運用していると、ある日突然アプリケーションが終了し、 ログを確認すると OOM Killer が動いていた── という経験をした方も多いのではないでしょうか。 OOM Kil…
あわせて読みたい


JavaプロセスがOOMで落ちる典型パターン【原因・確認・対処を完全整理】
Linuxサーバー上で稼働しているJavaアプリケーションが、 突然終了し、ログを見ると OutOfMemoryError や OOM Killer が発動していた──。 Javaは「ヒープサイズを指定し…
