サーバーが重い、ある処理が終わらない――そんなとき最初にやることは「今何が動いているか」を把握することです。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。kill や systemctl での操作対象を指定するときに使います。
%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
リアルタイムで変化を追うなら top や htop が便利です。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 の出力に見えますが、基本的な読み方は変わりません。
「コマンドは打てる。次は”現場で通用する型”を最短で身につけたい」——そんなあなたへ。
ネットの断片的なTipsをコピペするだけでは、体系的な運用スキルはなかなか積み上がりません。リナックスマスター.JPの無料メルマガ「リナマガ」では、現場で実際に使うLinuxサーバー運用の考え方を、順を追って実務目線でお届けしています。いま登録された方には、安全なサーバー構築の「型」をまとめた『Linuxサーバー構築入門マニュアル(図解60P)』を完全無料でプレゼント中です。
>> 図解60P『Linux入門マニュアル』を無料で受け取る
(メルマガ登録は10秒・いつでも解除OK)
※ 「独学の時間がもったいない」「プロから現場の技術を最短で学びたい」という本気の方には、2日で実務レベルが身につく初心者向けハンズオンセミナーもご用意しています。
