LinuxLow

Zombie Processes in Linux: How to Find and Eliminate

This article explains the nature of zombie processes in Linux and provides practical methods for their elimination. You'll learn how to locate zombie processes and apply the correct commands to clean up your system.

Updated at February 16, 2026
10-15 minutes
Easy
FixPedia Team
Применимо к:Linux 5.x+Ubuntu 20.04+CentOS 8+Debian 11+

What is a Zombie Process in Linux

A zombie process (zombie process) is a process that has already finished its execution, but its entry remains in the system's process table. This happens when the parent process fails to read the child's exit status using the wait() system call or one of its variants.

In the output of commands like ps aux or top, such a process is displayed with the status Z. A zombie process consumes no CPU time or RAM, but it occupies an entry in the process table (and therefore one of the available process identifiers — PID).

Usually, a zombie process is a temporary state that lasts microseconds. However, if the parent process "forgets" about its child, the zombie can remain in the system indefinitely.

What does the error look like?

$ ps aux | grep Z
USER       PID  %CPU %MEM    VSZ   RSS TTY      STAT START   TIME COMMAND
root      1234   0.0  0.0      0     0 ?        Z    10:00   0:00 [defunct] <process_name>

The [defunct] symbol in the COMMAND column clearly indicates a zombie process.

Causes

Zombie processes appear due to one primary cause and several indirect ones:

  1. The parent process does not call wait(). This is the most frequent cause. After the child process terminates (e.g., via exit()), the kernel stores information about its termination (return code, resource usage) in the process structure. The parent must read this information using wait() or waitpid(). If the parent fails to do so, the child's entry remains in the process table as a "zombie".
  2. The parent process is "hung" or mishandles signals. If the parent process ignores the SIGCHLD signal (which the kernel sends upon a child's termination) or terminates itself without waiting for its children, this leads to a zombie.
  3. A programming error. The parent process code might lack a wait() call after fork(), or it could be blocked on another action (e.g., waiting for I/O).
  4. An error in a system script or daemon. Some old or poorly written daemons can create zombies when handling requests.

How to Eliminate Zombie Processes

Since a zombie process is already dead, it cannot be "killed". The only way to free its entry in the process table is to make the parent process read the exit status. If the parent is unable or unwilling to do this, you must terminate the parent itself.

Method 1: Send a SIGCHLD Signal to the Parent Process

This is the cleanest method. The SIGCHLD signal (child termination signal) can cause a parent process that handles it correctly to invoke wait() and "reap" the zombie.

  1. Find the zombie process's parent process ID (PPID) (from the ps aux output).
  2. Send it the signal:
    kill -SIGCHLD <PPID>
    
    or simply:
    kill -18 <PPID>
    
  3. Check if the zombie is gone: ps aux | grep 'Z'.

⚠️ Important: Many programs do not have a custom handler for SIGCHLD by default. In this case, the kernel simply ignores the signal, and the zombie will remain.

Method 2: Terminate the Parent Process

If the signal didn't help, the most reliable method is to terminate the parent process. After this, the zombie process becomes an "orphan" and is inherited by the special init process (PID 1) or systemd (on modern systems). The init process periodically executes wait() for all its child processes, so the zombie will be automatically cleaned up.

  1. Ensure the parent's PID (PPID) is correct and you are prepared to terminate it. Caution: Terminating a system process (e.g., sshd, cron) may cause temporary service unavailability.
  2. Send a termination signal:
    kill <PPID>
    
    If the process does not respond, use forceful termination:
    kill -9 <PPID>
    
  3. After terminating the parent, check the process list. The zombie should be gone.

Method 3: Restart the Parent Process (if it's a Service)

If the parent process is a system daemon (e.g., apache2, nginx, mysql), the correct solution is to restart it via the service manager.

For systemd:

sudo systemctl restart <service_name>

For SysVinit (older systems):

sudo service <service_name> restart

Restarting the service guarantees that a new instance of the parent process will begin correctly managing its child processes.

Method 4: Debug and Fix the Source Code (for Developers)

If zombie processes constantly appear in your own application, you need to fix its code.

  1. Locate places in the parent process code that come after fork().
  2. Ensure that immediately after fork() in the parent branch, there is a call to wait() or waitpid() to collect the child's exit status.
  3. If the parent must run concurrently with the child, you need to:
    • Set up a handler for the SIGCHLD signal using signal() or sigaction().
    • Inside the handler, call waitpid() in a loop (to reap all terminated children).
    • Or periodically (with a non-blocking call) check for terminated children.

Example of a correct handler in C:

#include <sys/wait.h>
#include <signal.h>

void sigchld_handler(int s) {
    while (waitpid(-1, NULL, WNOHANG) > 0);
}

// In main(): signal(SIGCHLD, sigchld_handler);

Prevention

To avoid the accumulation of zombie processes in the future:

  1. For system administrators: Regularly check the process list for zombies (ps aux | grep 'Z'), especially after starting/stopping critical services. If zombies appear due to a specific daemon, look for updates for that software or report a bug to the developers.
  2. For developers:
    • Always handle the SIGCHLD signal in parent processes that create children via fork().
    • Use a non-blocking waitpid(-1, &status, WNOHANG) call in a loop inside the handler to reap all terminated children.
    • Consider using higher-level constructs (e.g., subprocess in Python, which automatically collects exit statuses) instead of direct fork/exec.
  3. Monitoring: Set up a simple script to monitor the number of zombie processes and alert if it exceeds, for example, 10.
    #!/bin/bash
    ZOMBIE_COUNT=$(ps aux | grep -c ' Z ')
    if [ "$ZOMBIE_COUNT" -gt 10 ]; then
        echo "Warning: $ZOMBIE_COUNT zombie processes detected!" | wall
        # You can also add email sending or a PagerDuty call
    fi
    

Conclusion

Zombie processes in Linux are primarily a consequence of errors in parent programs, not a critical system problem. They consume negligible resources, but their accumulation indicates malfunctioning software. In most cases, simply terminating the zombie's parent process is enough, after which the kernel will clean up its entry automatically. For a permanent fix, developers need to correct the code, while administrators should monitor service health and keep software updated.

F.A.Q.

How does a zombie process differ from an orphan process?
Can zombie processes burden the system?
How to prevent zombie processes from appearing?
Why doesn't the kill -9 command work on zombies?

Hints

Identify zombie processes
Ensure the parent process exists
Send SIGCHLD signal to the parent
Terminate the parent process (with caution)
Check the result
FixPedia

Free encyclopedia for fixing errors. Step-by-step guides for Windows, Linux, macOS and more.

© 2026 FixPedia. All materials are available for free.

Made with for the community