1. 僵尸进程定义
僵尸进程是当子进程比父进程先结束,而父进程又没有回收子进程,释放子进程占用的资源,此时子进程将成为一个僵尸进程。如果父进程先退出 ,子进程被init接管,子进程退出后init会回收其占用的相关资源。
2. 僵尸进程危害
由于子进程的结束和父进程的运行是一个异步过程,即父进程永远无法预测子进程 到底什么时候结束. 那么会不会因为父进程太忙来不及wait子进程,或者说不知道 子进程什么时候结束,而丢失子进程结束时的状态信息呢? 不会。因为UNⅨ提供了一种机制可以保证只要父进程想知道子进程结束时的状态信息, 就可以得到。这种机制就是: 在每个进程退出的时候,内核释放该进程所有的资源,包括打开的文件,占用的内存等。但是仍然为其保留一定的信息(包括进程号the process ID,退出状态the termination status of the process,运行时间the amount of CPU time taken by the process等)。直到父进程通过wait / waitpid来取时才释放. 但这样就导致了问题,如果进程不调用wait / waitpid的话,那么保留的那段信息就不会释放,其进程号就会一直被占用,但是系统所能使用的进程号是有限的,如果大量的产生僵尸进程,将因为没有可用的进程号而导致系统不能产生新的进程. 此即为僵尸进程的危害,应当避免。
3. 如何查看自己Linux服务器的僵尸进程
在Linux操作系统中,输入top指令就可以查看
注意看整个界面的第二行,
最后一个zombie的前面的数字就是代表僵尸进程的数量,这里我们看到僵尸进程数量不为0,那么我们需要来清除一下僵尸进程。
4. 先找到僵尸进程的父进程然后kill -9 杀死
接下来需要确定僵尸进程的相关信息,比如父进程ppid、僵尸进程的pid以及命令行等信息。可以执行如下命令
ps -e -o stat,ppid,pid,cmd | egrep '^[Zz]'
说明:
- ps:ps命令用于获取当前系统的进程信息.
- -e:参数用于列出所有的进程
- -o:参数用于设定输出格式,这里只输出进程的stat(状态信息)、ppid(父进程pid)、pid(当前进程的pid),cmd(即进程的可执行文件。
- egrep:是linux下的正则表达式工具
- ‘1’:这是正则表达式,表示第一个字符的位置,[Zz],表示z或者大写的Z字母,即表示第一个字符为Z或者z开头的进程数据,只所以这样是因为僵尸进程的状态信息以Z或者z字母开头。
然后可以kill -9 父进程pid,假设父进程pid为 9635
kill -9 9635
现在大多数linux系统,也会将僵尸进程标识为defunct,所以你也可以通过如下命令来获取僵尸进程信息。
ps -ef | grep "defunct"
一般来说先用kill命令发送强制终止的信息,结束子进程。如下图所示,这时候子进程是没有办法结束的。
所以,这时候需要用kill -9来强制终止父进程。
杀死父进程之后可以再次用top命令来看
上面的方法是通过结束父进程从而结束僵尸进程,这只能算是一个比较理想的情况 ,很多时候遇到僵尸进程我们不能结束父进程,比如父进程是init进程,那一旦结束父进程,整个系统就挂掉了,这时候则可以考虑挂起子进程,这相当于“曲线救国”。一个进程一旦挂起就相当于“什么都不做了”。可以通过执行如下命令来挂起进程。
kill -HUP 进程pid
kill -hup 2563