プロセスの調査
リソースを食っている犯人を特定するには、プロセス単位で見ます。top や htop はCPU・メモリ順に並べ替えられるので、上位を占めるプロセスをすぐ見つけられます。ps aux と grep を組み合わせれば、特定の名前のプロセスとそのPIDを探せます。応答しなくなったプロセスは kill にPIDを渡して終了させ、止まらない場合は kill -9 で強制終了します。終了しても消えないゾンビプロセスは、親プロセス側の後始末待ちが原因です。
リソース監視でCPUやメモリが逼迫していると分かった。だが、それで終わりではない。次の仕事は「その資源を食っている犯人」をプロセス単位で突き止めることだ。
システム全体が重いのは結果であって、たいていは特定の暴走プロセスや、メモリを抱え込んだプロセスが原因なのだ。
プロセスを一覧して、上位を占めているもの・状態がおかしいものを見つけ、必要なら終了させる。この一連の操作ができると、目の前の障害に直接手を打てるようになる。ここでは犯人の特定から、安全な止め方までを順に押さえる。
🔫 暴走している犯人を炙り出す
もっとも手早いのは top(や改良版の htop)で並べ替えることだ。top を開いた状態で大文字の P を押すとCPU使用率の高い順、M を押すとメモリ使用率の高い順に並び替わる。
システムが重いとき、この上位に張り付いているプロセスが第一容疑者だ。
各行には PID(プロセス番号)、USER(所有者)、%CPU、%MEM、COMMAND(コマンド名)が並ぶ。だから「どのユーザの何というプログラムが、CPUを何パーセント使っているか」が一目で分かる。
htop ならコアごとの使用率バーや、プロセスのツリー表示(F5)も使え、親子関係まで含めて状況をつかめる。どのプロセスから派生したものかが見えるので、「大量に湧いている子プロセスの親はどれか」を突き止めるのにも役立つ。
特定の名前のプロセスを狙って探したいときは、ps と grep の組み合わせが定番だ。ps aux はシステム上の全プロセスを詳細表示するので、ps aux | grep nginx のようにパイプでつなぐと、nginx を含む行だけが抜き出せる。出力の2列目が、そのプロセスの PID だ。
なお grep 自身も検索結果に紛れ込むことがある。気になる場合は ps aux | grep [n]ginx のように先頭文字を角括弧で囲むと、grep の行を除外できる。
名前から PID だけを直接知りたいときは pgrep nginx を使う。該当プロセスの PID が一覧で返り、後続の操作にそのまま渡せて便利だ。狙ったプロセスの PID さえ分かれば、次の操作で対象を指定できる。
🚦 STAT列の1文字が告げること
犯人を見極めるうえで、プロセスの状態を表す STAT 列(ps aux で表示される)も重要な手がかりだ。
先頭1文字が状態を表す。R は実行中または実行可能、S はスリープ(イベント待ちで休止中)、D は割り込み不可のスリープ(多くはディスクI/O待ちで、ここに張り付くプロセスが多いとI/Oが詰まっているサイン)、T は停止中、Z はゾンビを表す。
たとえば %CPU が高いまま STAT が R で張り付いているプロセスは暴走を疑い、D のプロセスが多ければI/O待ちを疑う、という読み方ができる。
🧟 ゾンビプロセスとは何者か
一覧に Z(ゾンビ)状態のプロセスを見つけて驚くことがある。
ゾンビプロセスとは、すでに処理を終えて実体は消えているのに、終了状態を親プロセスが受け取っておらず、プロセス管理表にエントリだけが残っている状態だ。
ゾンビ自体はCPUやメモリをほとんど消費しないので、少数なら実害はない。
問題は、ゾンビに対して kill を送っても消えないという点だ。すでに死んでいるものは殺せないからである。
ゾンビが消えないのは、親プロセスが後始末(子の終了状態の回収)をサボっているのが原因だ。対処するなら、親プロセスの側を再起動するか修正する。ゾンビが大量に溜まり続ける場合は、親プログラムのバグを疑うサインだ。
🔪 kill は本当に「殺す」コマンドか
応答しなくなったプロセスや、資源を食い続ける有害なプロセスは kill で終了させる。書式は kill PID で、top や ps で調べた PID を渡す。
kill という名前は物騒だが、実態はプロセスに「シグナル」という合図を送るコマンドだ。
何も指定しなければ既定で15番(SIGTERM)が送られる。これは「後片付けをして終了してください」という穏やかな依頼である。
プログラムは開いているファイルを閉じ、データを保存してから自分で終了できる。だから、まずはこの既定の kill を試すのが作法だ。
通常の kill で止まらないときの最終手段が kill -9 PID(SIGKILL)だ。-9 はカーネルがプロセスを問答無用で打ち切るため確実に止まるが、後片付けの機会を与えないので、書きかけのデータが壊れる恐れがある。
だからこそ「まず15、それでも駄目なら9」の順番が大切で、いきなり -9 を使う癖は避ける。
なお、自分以外のユーザが起動したプロセスを止めるには sudo kill PID のように管理者権限が必要だ。
複数のプロセスをまとめて止めたいときは、名前で指定できる pkill nginx や killall nginx も使える。ただし名前が一致するものを一網打尽にするため、対象を取り違えないよう慎重に使う。
✅ 特定から検証まで一本に通す
現場での典型的な流れはこうだ。システムが重い。top を開いて P や M で並べ替え、上位の暴走プロセスを特定する。
そのプロセスが安全に止めてよいものか(重要なサービスでないか)を確認する。まず kill PID(SIGTERM)を試し、止まらなければ kill -9 PID で強制終了する。top で資源使用が落ち着いたかを検証する。
ここで犯人のプロセスを特定する作業は、リソース監視で見つけたボトルネック(CPUなりメモリなりが頭打ちになっている箇所)を、具体的な「どのプロセスのせいか」へと結びつける段階にあたる。全体の症状と個別の犯人がつながって初めて、的確に手を打てる。
止めて終わりにせず、「なぜそのプロセスが暴走したのか」をログ(journalctl)で追うところまでやると、再発防止につながる。
プロセスを正しく見て、状態を読み、適切なシグナルで止める。この型が、障害対応の実行段階の中心になる。