1. Overview
In this tutorial, we’ll learn about zombie processes and ways to clean them. First, we’ll understand the various process states. Then, we’ll check ways to identify the zombie processes. Finally, we’ll arrive at solutions to our problem.
2. What Is a Zombie Process
Zombie processes in Linux are sometimes also referred to as defunct or dead processes. They’re processes that have completed their execution, but their entries are not removed from the process table.
2.1. Process States
Linux maintains a process table of all the processes running, along with their states. Let’s briefly overview the various process states:
- Running (R): These processes are currently running or runnable.
- Waiting (S/D): These are the processes that are waiting for an event or a resource. The wait can either be an interruptible sleep (S) or an uninterruptible sleep (D).
- Stopped (T): We can stop a Linux process by sending an appropriate signal.
- Zombie (Z): When a process finishes its task, it releases the system resources it was using and cleans up its memory. However, its entry from the process table is not removed, and its status is set as EXIT_ZOMBIE.
We’ll gain a better understanding of the concept of zombie processes in the next subsections.
2.2. Creation of Zombie Processes
When a process completes its job, the Linux kernel notifies the exiting process’s parent by sending the SIGCHLD signal. The parent then executes the wait() system call to read the status of the child process and reads its exit code. This also cleans up the entry of the child process from the process table, and hence, the process finishes.
However, if a parent process isn’t programmed to execute the wait() system call on the creation of the child process, proper cleanup doesn’t happen. In such cases, the parent process cannot monitor the state changes of the child processes, and eventually, it ignores the SIGCHLD signal. This causes the zombie state of the finished process to stay in the process table, and hence it appears in the process list as a zombie process.
Another case of interest is when a parent process is unable to handle or receive the SIGCHLD signal from the child process. Such cases also lead to zombie creation.
2.3. Identification of Zombie Processes
We can identify the list of zombies using the ps command:
$ ps ux
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
shubh 9 0.0 0.0 16916 2760 tty1 S Dec19 0:00 /bin/bash --login
shubh 108 0.0 0.0 0 0 tty1 Z 16:25 0:00 [zombie] <defunct>
shubh 109 0.0 0.0 17384 1928 tty2 R 16:25 0:00 ps ux
As observed from the output, the Z in the STAT column or zombie or
Let’s further filter the output based on the Z process state using the awk command:
$ ps ux | awk '{if($8=="Z") print}'
shubh 108 0.0 0.0 0 0 tty1 Z 16:25 0:00 [zombie] <defunct>
Another convenient method for checking the number and list of zombie processes is to use the top command:
$ top
Tasks: 8 total, 1 running, 6 sleeping, 0 stopped, 1 zombie
%Cpu(s): 0.7 us, 1.6 sy, 0.0 ni, 96.5 id, 0.0 wa, 1.2 hi, 0.0 si, 0.0 st
KiB Mem : 8269412 total, 3161228 free, 4878832 used, 229352 buff/cache
KiB Swap: 15483260 total, 14830144 free, 653116 used. 3256848 avail Mem
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 20 0 8936 192 148 S 0.0 0.0 0:00.17 init
8 root 20 0 8936 96 56 S 0.0 0.0 0:00.00 init
9 shubh 20 0 16916 2748 2640 S 0.0 0.0 0:00.43 bash
76 root 20 0 8936 224 184 S 0.0 0.0 0:00.00 init
77 shubh 20 0 16784 3432 3332 S 0.0 0.0 0:00.35 bash
161 shubh 20 0 0 0 0 Z 0.0 0.0 0:00.00 zombie
162 shubh 20 0 17624 2084 1508 R 0.0 0.0 0:00.00 top
Here, along with the other details, we can also see the number of zombie processes in the summary at the top of the output.
3. Cleaning a Zombie Process
We can’t really kill a zombie process since it’s already dead. However, there are a few workarounds we can use to clean up a zombie process.
3.1. Using SIGCHLD Signal
We can manually send the SIGCHLD signal to the parent of a zombie process. Consequently, it will imitate the parent to trigger the wait() system call, which will clean up the defunct child process from the process table.
Let’s find the parent id of our defunct process:
$ ps -A -ostat,pid,ppid | grep -e '[zZ]'
Z 108 103
This lists the STAT column, process id, and parent process id of zombie processes. Next, let’s send the SIGCHLD signal to the parent process using the kill command:
kill -s SIGCHLD 103
However, it isn’t really guaranteed that sending the SIGCHLD signal to the parent will kill a zombie process. It works only in cases where parent processes can handle the SIGCHLD signals.
3.2. Killing the Parent Process
If the method discussed in the previous section is unable to clear the defunct process, we should consider killing its parent process:
kill -9 103
Here, 103 is the parent id of our defunct process with PID 108.
However, killing a parent can affect all its child processes. Hence, we should exercise extra caution and must identify the impact before killing a parent process.
If a lot of zombie processes are present, or if the parent of the zombie process is the init process (with pid=1), we can also consider a system reboot to get rid of the defunct processes.
4. Conclusion
In this tutorial, we studied methods to clean up a zombie process.
In the beginning, we discussed the various process states in Linux. Then, we examined the situations that can lead to the creation of a zombie process. Next, we saw different ways to find zombie processes in our system. Finally, we discussed the solutions to our problem.