# `top` に出てくる「ゾンビ (zombie)」とは?原因・影響・確認と解消方法 Linuxを `top` で監視していると、Tasks(プロセス)行に `1 zombie` のような表示が出ることがあります。 ```text top - 16:03:19 up 7:09, 1 user, load average: 2.24, 2.21, 2.29 Tasks: 392 total, 1 running, 390 sleeping, 0 stopped, 1 zombie ... ``` ![시스템엔지니어가 좀비를 발견하고 당혹스러워하는 유머스러운 이미지](/media/whitedec/blog_img/85732501dbee47c0aea504d7d0f70c07.webp) この「ゾンビ」は何で、システムにどんな影響があるのでしょうか。この記事では、ゾンビプロセスの正体と、見つけ方・対処方法を手順で整理します。 --- ## ゾンビプロセス(Zombie Process)とは {#sec-f3b8b4a201c7} ゾンビプロセスは、**終了した子プロセスの情報が、親プロセスに回収されずにプロセステーブルに残っている状態**のことです。重要なのは、ゾンビは「動いているプロセス」ではなく、**終了済み**だという点です。 プロセスの流れで見ると理解しやすいです。 1. **生成(fork)**: 親プロセスが子プロセスを作成します(`fork()`)。 2. **実行(exec)**: 子プロセスが処理を実行します。 3. **終了(exit)**: 子プロセスが終了します(`exit()`)。 4. **終了通知(SIGCHLD)**: 子が終了すると、カーネルは親に `SIGCHLD` を送り、子の終了ステータスなどをプロセステーブルに一時的に保持します。 5. **回収(wait)**: 親プロセスが `wait()` / `waitpid()` で終了ステータスを取得(回収)すると、カーネルはそのエントリを完全に削除します。 **ゾンビ**はこの **4〜5の間**に留まっている状態です。つまり、 * 子プロセスは終了している * しかし親が `wait()` を呼ばないため、終了情報だけが残っている ということです。 --- ## どんな影響があるのか {#sec-5de25b45901b} ゾンビは終了済みなので、通常は **CPUを使いません**。メモリも、実行中プロセスのようには消費しません。 ただし、ゾンビは **プロセステーブル上のエントリ(PID)を占有**します。少数(1〜数個)なら大抵は問題になりませんが、親プロセスの不具合などで回収されないゾンビが増え続けると、 * PIDが枯渇して新しいプロセスが作れない * 結果としてサービス起動やログイン、ジョブ実行などが失敗する といった深刻な障害につながり得ます。 --- ## ゾンビプロセスの確認方法(PIDと親PIDを特定する) {#sec-f48527de207e} `top` は「ゾンビの数」を出すだけなので、どのプロセスがゾンビかは `ps` で確認します。`STAT`(状態)列が **`Z`** のものがゾンビです。 ```bash # 全体を見つつ Z を含む行を絞り込む ps -elf | grep ' Z ' # STAT 列がちょうど Z のものだけ出す(環境によって列がズレる場合あり) ps aux | awk '$8=="Z"' ``` 例: ```text 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 / STAT**: `Z`(ゾンビ) * **PID**: `5021`(ゾンビのPID) * **PPID**: `5000`(回収していない親プロセスのPID) * **CMD**: `[defunct]`(終了済みだが片付いていないことを示す表示) --- ## 解消方法:狙うべきは「ゾンビ」ではなく「親プロセス」 {#sec-fc97fbb305d0} 大事な前提として、**ゾンビプロセスは `kill` で消せません**。すでに終了していて、シグナルを受け取って処理する実体がないからです。 ```bash kill -9 5021 # ゾンビPIDを指定しても基本的に解決しない ``` ゾンビを消す唯一の道は、**親プロセスが `wait()` を実行して終了ステータスを回収すること**です。したがって対処は「親」に向きます。 --- ## ステップ1:親プロセスに SIGCHLD を送る(まず試す) {#sec-3db3078a894e} 親が `SIGCHLD` を正しく処理する実装であれば、シグナルをきっかけに `wait()` を実行して回収することがあります。 ```bash kill -s SIGCHLD 5000 ``` これでゾンビが消えるなら、親プロセス側の回収処理は動くが、通知やタイミングの問題だった可能性があります。 --- ## ステップ2:親プロセスを終了する(最後の手段) {#sec-98c193d4de88} ステップ1で変化がない場合、親プロセスが停止している/回収処理に問題がある/シグナル処理が壊れている、などが考えられます。最終手段として親を終了します。 ```bash kill 5000 # 終了しない場合 kill -9 5000 ``` ### 親を止めるとなぜ片付くのか {#sec-1e40ad2007bf} Linuxでは親が死ぬと子プロセスは孤児になります。孤児になった子は通常、**PID 1(init / systemd)** に引き取られます。PID 1 は終了した子を回収する役割を持つため、ゾンビも速やかに回収されます。 ### 注意点 {#sec-2bd571fbd6e9} 親プロセスが重要なサービス(DBやWebサーバなど)だと、停止すると別の問題が発生します。事前に必ず確認してください。 ```bash ps -p 5000 -o pid,ppid,cmd ``` --- ## まとめ {#sec-4207f2c5cd65} * ゾンビプロセスは、**終了済みの子プロセスが親に回収されず、プロセステーブルに残っている状態**。 * 通常はCPUやメモリをほぼ使わないが、**PID(プロセステーブルの枠)を消費**する。 * 少数ならよくあるが、増え続ける場合は対処が必要。 * 特定は `ps` で `STAT=Z` を探し、**PPID(親)を確認**する。 * 解消はゾンビ本人ではなく、**親プロセスに回収させる**のが基本。 * `kill -s SIGCHLD <親PID>` * それでも無理なら親を停止(影響範囲を必ず確認) --- ## 連関ポスト {#sec-9b8987393ab9} * [Linuxスクリプトの先頭行の意味とは? #!/usr/bin/env bash と #!/bin/bash の違いと使い分け](/ja/whitedec/2025/12/12/linux-script-first-line-env-vs-bin-bash/) * [Linuxでのジョブスケジューリング:cronとsystemd timerの比較](/ja/whitedec/2025/12/12/linux-scheduling-cron-vs-systemd-timer/)