🐧 Linux 総合学習プラットフォーム
プロセス監視/障害対応 ・ 中級

プロセスの調査

リソースを食っている犯人を特定するには、プロセス単位で見ます。top や htop はCPU・メモリ順に並べ替えられるので、上位を占めるプロセスをすぐ見つけられます。ps aux と grep を組み合わせれば、特定の名前のプロセスとそのPIDを探せます。応答しなくなったプロセスは kill にPIDを渡して終了させ、止まらない場合は kill -9 で強制終了します。終了しても消えないゾンビプロセスは、親プロセス側の後始末待ちが原因です。

リソース監視でCPUやメモリが逼迫していると分かったら、次の仕事は「その資源を食っている犯人」をプロセス単位で突き止めることです。システム全体が重いのは結果であって、たいていは特定の暴走プロセスや、メモリを抱え込んだプロセスが原因です。プロセスを一覧して、上位を占めているもの・状態がおかしいものを見つけ、必要なら終了させる——この一連の操作ができると、目の前の障害に直接手を打てるようになります。ここでは犯人の特定から、安全な止め方までを順に押さえます。

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)を読む

犯人を見極めるうえで、プロセスの状態を表す 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)で追うところまでやると、再発防止につながります。プロセスを正しく見て、状態を読み、適切なシグナルで止める——この型が、障害対応の実行段階の中心になります。

この項目に出てくる用語

ゾンビプロセスぞんびぷろせす
終了したのに親が後始末していないため一覧に残るプロセス。
ボトルネックぼとるねっく
全体の性能を律速している最も詰まっている箇所。

関連コマンド

pstophtopkill

▶ 学習アプリでこの続きを学ぶ・演習する