Linuxシステムを top コマンドで監視していると、'プロセス (Tasks)' ラインに 1 ゾンビ (zombie) のような項目を見つけることがあります。
top - 16:03:19 up 7:09, 1 user, load average: 2.24, 2.21, 2.29
作業: 392 総計, 1 実行, 390 待機, 0 停止, 1 ゾンビ
...
この「ゾンビ」は何であり、システムにどのような影響を与えるのでしょうか?この記事では、ゾンビプロセス(Zombie Process)の正体とそれを確認し解決する方法を明確に説明します。
ゾンビプロセス(Zombie Process)とは何か? 🧟
理解しやすくプロセスのライフサイクルに例えてみましょう。
-
誕生 (Fork): 親プロセス(Parent Process)が子プロセス(Child Process)を生成します (
fork()). -
実行 (Exec): 子プロセスが自身の作業を行います。
-
終了 (Exit): 子プロセスが作業を完了し終了します (
exit()). -
収穫 (Wait): 子プロセスが終了すると、OS(カーネル)はそのプロセスのPID、終了ステータスなどの情報をプロセステーブルに残します。そして親プロセスに
SIGCHLD(子が終了した) シグナルを送ります。 -
親プロセスはこのシグナルを受け取り
wait()システムコールを呼び出して子の終了ステータス情報を「収穫」する必要があります。この情報が収穫されると、カーネルは初めてプロセステーブルから子の項目を完全に削除します。
ゾンビプロセスはまさに4番と5番の間の状態に閉じ込められたプロセスです。つまり、子プロセスは実行を完了し終了しましたが、親プロセスがまだ wait() を呼び出して終了ステータスを収穫していない状態です。
名前の通り、このプロセスは死んでいる状態(実行中でない)です。したがって、CPUやメモリといったシステムリソースを消費することはありません。
ゾンビプロセスはなぜ問題になるのか?
ゾンビプロセス自体はシステムリソースをほとんど使用していませんが、プロステーブルの一スロット(PID)を占有します。
もし親プロセスのバグなどによりゾンビプロセスが積み重なり整理されない場合、システムが割り当てられるPIDの数(最大値)に達してしまう可能性があります。この場合、システムはもはや新しいプロセスを生成できなくなり、深刻な障害に繋がる可能性があります。 top で1~2個のゾンビが見えることは珍しくありませんが、この数が増え続ける場合は対処が必要です。
ゾンビプロセスの確認と識別方法
top コマンドはゾンビの _個数_ だけを表示します。どのプロセスがゾンビ状態なのか、その親は誰なのかを確認するには ps コマンドを使用する必要があります。
最も簡単なのは、ps コマンドの STAT (状態)列で'Z'として表示されたプロセスを探すことです。
# システム上のすべてのプロセスを詳細に見ながら 'Z' 状態(ゾンビ)をフィルタリング
ps -elf | grep ' Z '
# または 'aux' オプションを使用 (8番目のカラム($8)が状態(STAT)です)
ps aux | awk '$8=="Z"'
例示出力 :
# ps -elf | grep ' Z '
F S UID PID PPID C PRI NI ADDR SZ WCHAN STIME TTY TIME CMD
0 Z user 5021 5000 0 80 0 - 0 exit 15:30 ? 00:00:00 [defunct]
上記の例で重要な情報は以下の通りです。
-
S (State):
Z(ゾンビ状態を意味する) -
PID:
5021(これがゾンビプロセスのPIDです) -
PPID:
5000(これがゾンビを収穫していない親プロセスのPIDです) -
CMD:
[defunct](終了したが整理されていないことを示す名前)
ゾンビプロセスの解決方法
最も重要な事実は、ゾンビプロセスは kill コマンドで殺すことができないということです。
kill -9 5021(上記のゾンビPID)
上記のコマンドは動作しません。ゾンビはすでに「死んでいる」状態だからです。 kill シグナルを処理する主体がいません。
ゾンビプロセスを解決する唯一の方法は、親プロセスが wait() を呼び出すことです。
ステップ1: 親プロセスにシグナルを送る (推奨)
最初に試みるべき方法は、親プロセス(PPID)に子の状態を確認するように SIGCHLD シグナルを手動で送ることです。
# 上記の親PID(5000)にSIGCHLDシグナルを送信
kill -s SIGCHLD 5000
これは親プロセスに「お前の子プロセスの一つが終了したので確認してみて!」と知らせる効果があります。正常にプログラムされた親であれば、このシグナルを受け取りゾンビを収穫して整理します。
ステップ2: 親プロセスを強制終了 (最後の手段)
もしステップ1がうまくいかない場合、親プロセス(PPID 5000)自体が停止しているか、wait() を呼び出すロジックに深刻なバグがあることを意味します。
この場合、親プロセスを強制終了することが唯一の解決策です。
# 親プロセス(PPID 5000)を終了
kill 5000
# それでも終了しない場合は強制終了
kill -9 5000
なぜ親を殺すと解決するのか?
Linuxでは親プロセスが死ぬと、その子プロセスたち(孤児プロセス)は自動的にinit プロセス(PID 1) または systemd によって養子にされます。 init プロセスは定期的に子の状態を確認し、終了した子(ゾンビを含む)を即座に収穫(reap)するように設計されています。
したがって、厄介者の親(PPID 5000)が亡くなれば、ゾンビ(PID 5021)は init の新たな子となり、 init が即座にゾンビを整理してくれます。
⚠️ 注意: 親プロセスを終了する前に
ps -p 5000(親PID) コマンドを使用して、そのプロセスがシステムの重要なサービス(例: DB, ウェブサーバーなど)でないか必ず確認してください。重要なサービスを強制終了するとさらに大きな障害が発生する可能性があります。
まとめ
-
ゾンビプロセスは実行が終了したが親が終了状態を収穫していない、プロセステーブルに残ったカスです。
-
リソースを消費しませんが、PIDを占有し、過剰に増えるとシステム障害を引き起こします。
-
ps -elf | grep ' Z 'コマンドでゾンビ(PID)とその親(PPID)を見つけることができます。 -
解決策はゾンビではなく親プロセス(PPID)を対象とします。
-
kill -s SIGCHLD <親PID>(推奨) -
kill <親PID>(最後の手段)
-
コメントはありません。