How to Find and Kill Zombie Processes on Linux Systems

undefined

In this mini post I’ll show you how to find and kill all zombie processes that may exist on your Linux Systems.

First, we need to define What is the Zombie process? and Why it exists?

A process is called a zombie process or defunct process if the process has been completed, but its PID and process entry remains in the Linux process table. A process is removed from the process table when the process is completed, and its parent process reads the completed process exit status by using the wait() system call. If a parent process fails to call wait() for whatever reason, its child process will be left in the process table, becoming a zombie.

How can we discover the existence of Zombie processes on Linux Systems?

Simply by using top command, this will show the status of all processes running on your Linux System. run the following command and notice it’s output:

# top

top - 21:55:52 up 47 days, 22:12, 1 user, load average: 0.00, 0.04, 0.05
Tasks: 98 total, 2 running, 92 sleeping, 0 stopped, 4 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni,100.0 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1883592 total, 312860 free, 889964 used, 680768 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 713172 avail Mem

From the above output, I’ve 4 zombie processes that completed their tasks and didn’t exit. It’s save to kill them, but first we need to list them.

How can we get the Zombie from process list…?
Its very simple. You can find out Zombie process with the following commands:

# ps aux |grep Z |grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2329 0.0 0.0 0 0 ? Zs Feb16 0:00 [systemctl] <defunct>
root 4546 0.0 0.0 0 0 ? Zs Feb13 0:00 [systemctl] <defunct>
root 16659 0.0 0.0 0 0 ? Zs 21:38 0:00 [systemctl] <defunct>
root 26350 0.0 0.0 0 0 ? Zs Feb19 0:00 [systemctl] <defunct>

OR

# ps aux |grep "defunct" |grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2329 0.0 0.0 0 0 ? Zs Feb16 0:00 [systemctl] <defunct>
root 4546 0.0 0.0 0 0 ? Zs Feb13 0:00 [systemctl] <defunct>
root 16659 0.0 0.0 0 0 ? Zs 21:38 0:00 [systemctl] <defunct>
root 26350 0.0 0.0 0 0 ? Zs Feb19 0:00 [systemctl] <defunct>

Now, we have the PID of the four zombie processes on our Linux System, let’s go and KILL THEM ALL using kill command, go ahead and run this command:

# kill -9 2329 4546 16659 26350

Hooray, we killed the zombie process, let’s double check, by running any of the above command:

# ps aux |grep "defunct" |grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND
root 2329 0.0 0.0 0 0 ? Zs Feb16 0:00 [systemctl] <defunct>
root 4546 0.0 0.0 0 0 ? Zs Feb13 0:00 [systemctl] <defunct>
root 16659 0.0 0.0 0 0 ? Zs 21:38 0:00 [systemctl] <defunct>
root 26350 0.0 0.0 0 0 ? Zs Feb19 0:00 [systemctl] <defunct>

Oh No, The Zombie Processes still exist on our Linux box, Kill command failed to kill them WHY?

Killing zombie processes is not obvious since zombie processes are already dead.

Hint:
1. A zombie process doesn’t react to signals.

How can we KILL the Zombie processes?

Simply, we have to kill it’s parent process. If the parent exited, the child would be orphaned and re-parented to init, which would immediately perform the wait(). In other words, they should go away once the parent process is done.

We need to find the PPID “the parent process ID” of the zombie processes using the following command and search for the zombie process PID:

# pstree -paul
.....
─monit,4647 -I
 │ ├─(systemctl,2329)
 │ ├─(systemctl,4546)
 │ ├─(systemctl,16659)
 │ ├─(systemctl,26350)
 │ └─{monit},464

In our example, the parent of the zombie process is the monit monitoring with PID 4647. Now we kill the monit process “the parent” to kill all it’s zombie processes, run the following command:

# kill -9 4647

Now, we check on the existence of ant zombie processes by using top and ps commands:

# top

op - 21:56:34 up 47 days, 22:13, 1 user, load average: 0.00, 0.04, 0.05
Tasks: 94 total, 1 running, 93 sleeping, 0 stopped, 0 zombie
%Cpu(s): 0.0 us, 0.0 sy, 0.0 ni, 99.8 id, 0.2 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 1883592 total, 300796 free, 902092 used, 680704 buff/cache
KiB Swap: 0 total, 0 free, 0 used. 701180 avail Mem

Hooray, zombie process count is ZERO,now ps command check

# ps aux |grep Z |grep -v grep
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND

No results found from ps command. We totally killed all our zombie processes.

Hint:
If you didn't find pstree command on your Linux, you need to install it.
For Centos Linux pstree command exists in a package called psmisc 
To install it run  yum install psmisc

Finally, There is another way to kill the zombie processes without the need for pstree command to get the parent process ID, we can get the PPID and PID of the zombie process using ps command as follow:

# ps axo stat,ppid,pid,comm | grep -w defunct
ZN 3615 4472 single <defunct>

In this example, we only have one zombie process, as shown by ps command, the parent process id of the zombie process is 3615.

To check the top command output, run

# top

top - 06:27:50 up 11 days, 20:10, 3 users, load average: 0.81, 1.01, 1.18
Tasks: 287 total, 1 running, 285 sleeping, 0 stopped, 1 zombie
%Cpu(s): 19.1 us, 2.1 sy, 0.0 ni, 78.8 id, 0.0 wa, 0.0 hi, 0.0 si, 0.0 st
KiB Mem : 16064460 total, 6182504 free, 5574520 used, 4307436 buff/cache
KiB Swap: 6279156 total, 5648764 free, 630392 used. 7962824 avail Mem

Indeed, we have one zombie process, now we kill it’s parent to kill it, run the following command:

# kill -9 3615

Now, we check

# ps axo stat,ppid,pid,comm | grep -w defunct

No output

# top

top - 06:33:40 up 11 days, 20:16, 3 users, load average: 1.36, 1.00, 1.10
Tasks: 288 total, 2 running, 286 sleeping, 0 stopped, 0 zombie
%Cpu(s): 19.4 us, 2.5 sy, 4.3 ni, 55.6 id, 18.0 wa, 0.0 hi, 0.1 si, 0.0 st
KiB Mem : 16064460 total, 6316164 free, 5377196 used, 4371100 buff/cache
KiB Swap: 6279156 total, 5648772 free, 630384 used. 8239736 avail Mem

Also, no output

Before we leave this post, there are more commands you use to get the number of zombie processes on your Linux:

To Know How many Zombie process running on your server…?

# ps aux | awk {'print $8'}|grep -c Z
4
# ps aux | awk '{ print $8 " " $2 }' | grep -wc Z
4
# ps aux | awk {'print $8'}|grep Z|wc -l
4

Finally, I hope this mini post helped you.

AND DO NOT FORGET TO START THE MONIT PROCESS AGAIN “The one in the first example” As Monit do a good job on monitoring and starting services.

If You Appreciate What We Do Here On Mimastech, You Should Consider:

  1. Stay Connected to: Facebook | Twitter | Google+
  2. Support us via PayPal Donation
  3. Subscribe to our email newsletters.
  4. Tell other sysadmins / friends about Us - Share and Like our posts and services

We are thankful for your never ending support.

Leave a Reply

Your email address will not be published. Required fields are marked *