OOM は Out Of Memory の略で、メモリが足りずに処理を続けられない状態です。
Linux では、この状態になるとカーネルが OOM Killer を動かし、プロセスを強制終了します。
「遅い」ではなく「突然消える」
OOM が厄介なのは症状の出方です。メモリ不足はエラーメッセージを残さず、プロセスがいきなり消えます。アプリ側のログには何も出ないため、原因を見誤りやすいところです。
確認するのはシステム側のログです。
dmesg -T | grep -i "out of memory"
journalctl -k | grep -i "killed process"
ここに Killed process ... (mysqld) のような行があれば、アプリが落ちたのではなくカーネルに殺されています。
巻き添えで別のものが死ぬ
もうひとつの落とし穴です。OOM Killer は「メモリを最も使っているプロセス」を優先して選ぶため、メモリを食ったビルド処理ではなく、常駐しているデータベースが終了させられることがあります。
「デプロイしたらDBが落ちた」という現象は、たいていこれです。ビルドと本番アプリを同じサーバーで動かさないのが根本対策になります。
起きたときにまず見るもの
- Swap があるか(
free -h)。無いと、少し超えただけで即死する - 同時実行数。ビルドの並列度を下げるだけで収まることが多い
- 本当にリークか。時間とともに増え続けるなら、増設しても再発する
VPS のようにメモリが小さい環境では、Swap を用意しておくだけで「落ちる」が「遅い」に変わります。遅い方が調査もできるぶんまだ扱いやすいという考え方です。
実務で見るポイント
- Docker ではコンテナごとに上限を設定できる。1つのコンテナがホスト全体を巻き込むのを防ぐ
- 監視はメモリ使用率だけでなく、OOM の発生自体をアラートにする
- 「増設したら直った」で終わらせず、増え方が正常かを確認する
空きメモリの監視では OOM に気づけない理由と、何を監視すればよいかは メモリ監視は正常なのにプロセスが落ちる|空きメモリではOOMを検知できない理由 で詳しく整理しています。