サーバ運用をしていると、CPU使用率は正常でメモリもそれほど使っていないように見えたのに、重要なプロセスが突然消えているという経験はありませんか?
ログを確認し、Out of memory: Killed process という記録があれば、それはアプリケーションのバグではなく、Linuxカーネルがシステム全体のクラッシュを避けるためにプロセスを強制終了したことを意味します。
このとき働いているのが OOM Killer(Out Of Memory Killer) です。この記事では、Linuxの普遍的なメモリ管理の仕組みと、プロセス消失を防ぐための具体的な対策を解説します。
1. Linuxのメモリ管理:「MemFree」を信じてはいけない
Linux運用における鉄則は、「MemFreeが少ない = メモリ不足」ではないという点です。Linuxカーネルは、空いている物理メモリがあればディスクI/Oを高速化するために「ページキャッシュ」として最大限に活用しようとします
作業机の例え
| 概念 | 例え |
|---|---|
| RAM (物理メモリ) | 作業机 |
| Swap | 倉庫(低速だが広い) |
| Page Cache | 机に広げた参照資料 |
Linuxは机の上が空いていると、次に使うかもしれない資料(キャッシュ)をどんどん広げます。そのため、freeコマンドでMemFreeがほぼ0に見えるのは、カーネルがリソースを100%効率的に使い切っている健全な状態を指します。
2. 真の余力を示す指標「MemAvailable」
監視において見るべきはMemFreeではなく、MemAvailableです。
- MemFree: 物理的に全く使われていない「完全な空き」
- MemAvailable: 新しいアプリを起動する際、スワップを発生させずに確保できる「推定余力」
MemAvailableは、カーネル内の si_mem_available() 関数によって算出されます。これにはMemFreeに加え、解放可能なキャッシュが含まれますが、システム維持に必要な「予約領域」はあらかじめ差し引かれています。
3. なぜ突然メモリが足りなくなるのか(オーバーコミット)
MemAvailableに余裕があっても安心できない理由、それがオーバーコミットです。
Linuxには、搭載されている物理メモリ以上のメモリ割り当てをプロセスに許可する仕組みがあります。プロセスがメモリを要求した際、実際にデータが書き込まれるまで物理メモリを割り当てない「遅延割り当て」を行うためです。
このため、複数のプロセスが一斉に「約束していたメモリを今使う」と動き出したとき、物理メモリが突如として枯渇し、システムは限界を迎えます。
4. OOM Killerの発動:システムの最終防衛ライン
物理メモリが枯渇し、カーネルがページキャッシュの破棄やスワップへの退避を試みてもメモリを確保できず、システムが稼働できなくなったとき、最終手段としてOOM Killerが発動します。
OOM Killerは、システム全体がフリーズ(Kernel Panic)するのを防ぐために、特定のプロセスを強制終了させてメモリを強制的に回収します。
5. OOM Killerは「誰」を殺すのか:oom_scoreの計算
OOM Killerは、被害を最小限にしつつ最大限のメモリを回収できるプロセスを論理的に選びます(計算式は割愛します)。その指標が oom_score です。
このoom_scoreの計算により、メモリを100%占有しているプロセスのスコアは「1000」になります。
6. 重要プロセスを保護する:oom_score_adj
特定の重要なプロセスを守りたい場合、oom_score_adj(-1000 ~ 1000)を設定して調整します。
- 1000: 最優先で殺される(キャッシュ用途のプロセスなど)
- -1000: OOM Killerの対象外(不死身)
systemdを利用している場合は、サービスファイル(.service)で次のように設定可能です。
OOMScoreAdjust=-5007. 実運用での対策
① Swapを「時間稼ぎ」の保険として設定する
Swapは単なるメモリの代わりではなく、カーネルがメモリを整理するためのバッファです。
スワップファイルを作成する際は、dd コマンドの使用が推奨されます。
# 2GBのSwapファイルを作成する例
sudo dd if=/dev/zero of=/swapfile bs=1M count=2048 status=progress
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile② PSI (Pressure Stall Information) を活用する
従来の「使用率」監視に加え、/proc/pressure/memory で確認できる PSI に注目しましょう。「メモリ待ちでプロセスがどれだけ失速しているか」を数値化できるため、OOMが発生する前の予兆をより正確に捉えられます。
まとめ
- MemFreeは0でも正常。 ページキャッシュが有効に働いている証拠。
- MemAvailableを見るべきだが、オーバーコミットによる急な枯渇に注意。
- OOM Killerはシステムを死守するための最終手段。
- 対策は「適切なSwap設定」と「PSI(圧力情報)による予兆監視」。
プロセスが突然消えたら、まずは dmesg や journalctl -k で「Out of memory」のログを探してみてください。そこには、システムが生き残るために下した決断の証跡が残っています。