【Ubuntu】メモリ不足の調べ方:free/top/ps と OOM Killer の見分け(原因特定→再発防止)

メモリ不足トラブルシューティング - free/top/ps

この記事で解決できること

  • サーバが重い/落ちる原因が「メモリ不足」かどうか判断できます
  • メモリを食っているプロセスを特定できます
  • OOM Killer(メモリ不足でOSがプロセスを殺す仕組み)が動いた痕跡を確認できます
  • "とりあえず再起動" で誤魔化さず、再発防止に繋げられます

結論(最短ルート)

メモリが怪しいときは、次の順で見れば迷いません。

  1. 全体把握free -h(メモリ/Swapの状況)
  2. 犯人候補top(RESが大きい、CPUも高い)
  3. 上位一覧ps aux --sort=-%mem | head
  4. OOM痕跡journalctl -k | grep -i oom
  5. 対処:原因プロセス/サービスへ(ログ、設定、メモリ上限、スケール、Swap)

目次

  1. メモリ不足っぽい症状
  2. free -h で全体を把握する
  3. top で"今重い犯人"を探す
  4. ps でメモリ上位一覧を確定する
  5. OOM Killer が動いたか確認する
  6. メモリ不足のタイプ分け
  7. 今すぐ復旧の手順
  8. Swap が絡むと激重になる
  9. やってはいけないこと

前提(対象環境)

  • OS:Ubuntu
  • 対象:サーバ触り始めた新人
  • sudo 可能
  • 目的:切り分けと復旧(+最低限の再発防止)

1. そもそもメモリ不足っぽい症状

「メモリ不足」は、見た目が色々です。

  • サーバが極端に遅い(SSHが重い、コマンドが返らない)
  • ある瞬間にアプリが落ちる / 502や503が増える
  • プロセスが突然死する(ログにエラーが残る)
  • 何度再起動しても時間が経つと同じ現象が起きる

重要:CPUが100%でも、原因がメモリ(スワップ地獄)なことがあります。CPUだけ見て原因を誤認しないようにします。

2. free -h で全体を把握する(最初の一手)

$ free -h

例(イメージ):

              total        used        free      shared  buff/cache   available
Mem:           2.0Gi       1.9Gi        30Mi       120Mi        70Mi        80Mi
Swap:          1.0Gi       1.0Gi         0Mi

見るポイント:

  • available:実質的に使えるメモリの目安(これが小さいと厳しい)
  • Swap:Swapがほぼ満タンなら危険信号(スワップスラッシングで激重になりやすい)

目安(ざっくり):

  • available が 数十MB → かなり危険(OOMや極端な遅さが起きやすい)
  • Swap が 常に増え続ける → 根本原因が放置されている可能性が高い

3. top で"今重い犯人"を探す(RESを見る)

$ top

見方(新人が見るべきはここ):

  • %MEM:メモリ使用率
  • RES:実メモリ使用量(重要)
  • %CPU:CPU使用率

topの操作(よく使う):

  • M:メモリ順に並べ替え
  • P:CPU順に並べ替え
  • q:終了

4. ps で"メモリ上位一覧"を確定する(証拠を作る)

$ ps aux --sort=-%mem | head -n 20

CPU上位も併せて見ると、原因の方向性が分かります。

$ ps aux --sort=-%cpu | head -n 20

よくあるパターン:

  • 1つのプロセスが巨大(例:java、node、php-fpm、python、db)
  • 同じ種類が大量(ワーカー暴走、プロセスが増殖)
  • Dockerコンテナが増殖

5. OOM Killer が動いたか確認する(ここが決定打)

OOM Killer は「メモリが足りないから、OSがプロセスを強制終了した」状態です。アプリが突然死する原因として非常に多いです。

5-1. カーネルログから探す(推奨)

$ sudo journalctl -k | grep -i oom | tail -n 50

5-2. killed process を探す

$ sudo journalctl -k | grep -i "killed process" | tail -n 50

5-3. dmesgでも確認可能

$ dmesg | grep -i oom | tail -n 50

典型ログ(イメージ):

Out of memory: Killed process 1234 (node) total-vm:... anon-rss:...

ここに 殺されたプロセス名 が出ます。それが原因の中心です。

6. "メモリ不足" の原因をタイプ分けする(対処が変わる)

タイプA:一時的なスパイク(瞬間的に増える)

  • バッチ処理、重い集計、画像処理など
  • 対処:処理の分離、メモリ上限/ワーカー数調整、スワップ追加、インスタンスサイズアップ

タイプB:リーク/増え続ける(時間経過で悪化)

  • Node/Python/Javaなどで長時間動かすと増える
  • 対処:アプリ側のメモリリーク疑い、ワーカー/プロセスの再起動設計、上限設定

タイプC:プロセス増殖(fork爆発・ワーカー過多)

  • php-fpmの子プロセスが増えすぎ、キュー/アクセス増でワーカーが増殖
  • 対処:子プロセス数/ワーカー数の上限設定、負荷試験・レート制限

7. "今すぐ復旧" の現実的手順(安全優先)

7-1. どのサービスが重いか分かっている場合:優先的にログを見る

$ sudo journalctl -u nginx -n 200
$ sudo journalctl -u app -n 200

7-2. サービス再起動(最終手段に近いが現場では必要)

$ sudo systemctl restart <service>
$ sudo systemctl status <service>

注意:再起動で治るなら、原因は "メモリが溜まる" 系が濃厚です。そのまま放置すると再発します。

8. Swap が絡むと"激重"になる(スワップ地獄の見分け)

Swapが増えてくると、メモリ不足→ディスクI/Oでさらに遅くなる地獄になります。

$ free -h

まずは "全体がswap使ってる" と分かれば十分です。

9. やってはいけないこと

やってはいけない1:原因を見ずに再起動を繰り返す

ログとOOM痕跡を見ない再起動は、毎回同じ事故を繰り返します。

やってはいけない2:Swapを"万能薬"だと思う

Swapは緊急回避としては有効ですが、根本対策ではありません。パフォーマンス悪化も招きます。

やってはいけない3:上限なしのワーカー/プロセス設定を放置する

php-fpmやアプリワーカーは、上限なしだとメモリを食い尽くします。"上限"を必ず設けてください。

コピペ用:メモリ不足調査テンプレ

# 1) 全体
free -h

# 2) 今の犯人(メモリ順に)
top

# 3) メモリ上位一覧(証拠)
ps aux --sort=-%mem | head -n 20

# 4) OOM痕跡(決定打)
sudo journalctl -k | grep -i oom | tail -n 50
sudo journalctl -k | grep -i "killed process" | tail -n 50

まとめ

  • free -havailableSwap をまず見る
  • ps aux --sort=-%mem で上位を確定
  • journalctl -k | grep -i oomOOMの有無 を確定
  • 再起動で一瞬治るなら、ほぼ確実に再発する。原因をタイプ分けして潰す

検証環境

本記事のコマンドは Ubuntu 24.04 LTS / bash 5.2 で動作確認済みです。

次に読む