【Ubuntu】メモリ不足の調べ方:free/top/ps と OOM Killer の見分け(原因特定→再発防止)
この記事で解決できること
- サーバが重い/落ちる原因が「メモリ不足」かどうか判断できます
- メモリを食っているプロセスを特定できます
- OOM Killer(メモリ不足でOSがプロセスを殺す仕組み)が動いた痕跡を確認できます
- "とりあえず再起動" で誤魔化さず、再発防止に繋げられます
結論(最短ルート)
メモリが怪しいときは、次の順で見れば迷いません。
- 全体把握:
free -h(メモリ/Swapの状況) - 犯人候補:
top(RESが大きい、CPUも高い) - 上位一覧:
ps aux --sort=-%mem | head - OOM痕跡:
journalctl -k | grep -i oom - 対処:原因プロセス/サービスへ(ログ、設定、メモリ上限、スケール、Swap)
目次
前提(対象環境)
- 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 -hの available と Swap をまず見るps aux --sort=-%memで上位を確定journalctl -k | grep -i oomで OOMの有無 を確定- 再起動で一瞬治るなら、ほぼ確実に再発する。原因をタイプ分けして潰す
検証環境
本記事のコマンドは Ubuntu 24.04 LTS / bash 5.2 で動作確認済みです。