MENU

稼働中のプロセスを把握してリソース問題の原因を特定する

サーバーが重い、ある処理が終わらない――そんなとき最初にやることは「今何が動いているか」を把握することです。ps aux 1行で全プロセスの一覧が取れます。まずこれを打ってから判断を始めましょう。

目次

まず全プロセスを一覧表示する

最も広く使われる確認コマンドがこちらです。BSD形式のオプションで、実行ユーザー・CPU・メモリ使用率をまとめて出力します。

ps aux

Ubuntu 24.04 / AlmaLinux 9 などの現代的な環境での実行例:

USER         PID %CPU %MEM    VSZ    RSS TTY      STAT START   TIME COMMAND
root           1  0.0  0.1 169712  11456 ?        Ss   09:01   0:02 /sbin/init
root         523  0.0  0.2  47524  18320 ?        Ss   09:01   0:00 /lib/systemd/systemd-journald
www-data    1042  0.3  1.2 421308  96280 ?        S    09:02   0:15 /usr/sbin/apache2 -k start
deploy      2841  8.7  4.5 823740 368124 ?        R    10:33   2:01 python3 /opt/app/worker.py
root        3102  0.0  0.0   7236   1092 pts/0    R+   10:41   0:00 ps aux

古い環境では ps -ef(UNIX形式)がよく使われていましたが、ps aux はCPU・メモリの使用率列が加わるため、負荷調査には aux が現場で定番です。

出力列の意味と実務で注目すべき項目

各列の意味を整理します。

USER:プロセスを実行しているOSユーザー。root で動いているサービスは最小権限の観点から要確認です。
PID:プロセスID。killsystemctl での操作対象を指定するときに使います。
%CPU:直近の測定区間におけるCPU使用率。ps はスナップショットなので、継続的な高負荷かどうかは top と合わせて判断します。
%MEM:RSSが全体メモリに占める割合。
VSZ:仮想メモリの確保量(KB)。大きくても必ずしも問題ではなく、RSS(実際に物理メモリに乗っているサイズ)と合わせて判断します。
TTY:端末との紐づき。? はデーモン(バックグラウンドサービス)を意味します。
STAT:プロセスの状態(後述)。
COMMAND:実行コマンドのフルパスと引数。[kworker] のように角括弧で囲まれているものはカーネルスレッドです。

STATフィールドで異常プロセスを見つける

STATは一見わかりにくいですが、実務でのトラブル切り分けに直結します。

R(Running):実行中またはCPUキュー待ち。R が多数並ぶときはCPU飽和を疑います。
S(Sleeping):割り込み可能なスリープ。通常の待機状態です。
D(Disk wait):ディスクI/O待ちで割り込み不可。kill しても消えないのがこのステータスの特徴で、D が大量に見えるときはストレージの遅延・詰まりを疑います。
Z(Zombie):終了済みだが親プロセスが回収していない状態。少数なら無害ですが、大量発生は親プロセスのバグを示します。kill -9 では消えません。
T:一時停止(シグナルまたはデバッガによる)。
修飾子 +:フォアグラウンドのプロセス群。s はセッションリーダー、l はマルチスレッドを示します。

ゾンビとDステータスをピンポイントで確認するコマンド:

# ゾンビプロセスを一覧
ps aux | awk '$8 ~ /Z/ {print}'

# ディスクI/O待ちプロセスを一覧
ps aux | awk '$8 ~ /D/ {print}'

CPU・メモリ消費上位を素早く特定する

サーバーが重いときは、まず上位消費プロセスを確認します。

# CPU消費上位10プロセス(ヘッダー行を含め11行)
ps aux --sort=-%cpu | head -11

# メモリ(RSS)消費上位10プロセス
ps aux --sort=-%mem | head -11

リアルタイムで変化を追うなら tophtop が便利です。htop はカラー表示でツリー構造も見やすく、F6 でソート列を切り替えながら対話操作できます。インストールしていない環境では top で十分です。

# 1秒ごとに更新してCPU順に表示
top -d 1

ある運用現場では、深夜バッチが暴走してサーバーを占有する事案が発生しました。ps aux --sort=-%cpu | head を cron で定期的にログに残しておくことで、翌朝に原因プロセスを特定できた事例があります。

特定のサービスやユーザーに絞り込む

全プロセスを眺めるのではなく、対象を絞って確認する方法です。

# プロセス名で検索(grep自身を除外するイディオム)
ps aux | grep '[n]ginx'

# pgrep でPIDのみ取得(-a でコマンド名も表示)
pgrep -a nginx

# 特定ユーザーのプロセスのみ表示
ps -u www-data

# 親子関係をツリー表示
ps -eo pid,ppid,user,stat,comm --forest | head -40

grep '[n]ginx' のように先頭1文字を [] で囲むと、grep自身がパターンにマッチしなくなります。監視スクリプトやワンライナーで誤検知を防ぐ定番の書き方です。

systemdサービスと紐づけて確認する

現代のLinuxではsystemdが多くのプロセスをCgroup(コントロールグループ)でまとめて管理しています。PIDがわかっているとき、それがどのsystemdサービスに属するかを確認するには次のコマンドを使います。

# PID 1042 がどのサービスに属するか確認
systemctl status 1042

# サービス名からプロセスと状態をまとめて確認
systemctl status nginx

# Cgroupツリーで全サービスのプロセス構成を確認
systemd-cgls

systemd-cgls を使うと、どのサービスがどのプロセス群を束ねているかをツリー形式で一覧できます。ps --forest では見えにくいsystemdの管理境界をひと目で把握できるため、マルチプロセス型サービスの調査に重宝します。

プロセスの存在確認だけでなく、起動失敗やクラッシュを調べる場合はログも合わせて確認します。

# nginxの直近50行のログを確認
journalctl -u nginx -n 50 --no-pager

# 直近のエラーのみ絞り込む
journalctl -u nginx -p err --since "1 hour ago" --no-pager

ps でプロセスの現在状態を把握し、journalctl でその前後の経緯を追う――この2ステップを組み合わせることで、「何が動いているか」と「なぜ止まったか(または暴走しているか)」を短時間でカバーできます。CentOS 6時代の /sbin/mingetty は現代のsystemdでは agetty に置き換わっており、仮想コンソールのプロセスも ps aux の出力に見えますが、基本的な読み方は変わりません。

<PR>この記事に関連するおすすめ書籍

新しいシェルプログラミングの教科書

現場で使えるシェルスクリプトの書き方を基礎から実務レベルまで解説。定型作業の自動化に役立ちます。

「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。

ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。

>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)

※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。

よかったらシェアしてね!
  • URLをコピーしました!
  • URLをコピーしました!

この記事を書いた人

目次