linux进程——僵尸进程和孤儿进程
最近完善了prometheus监控,发现有几个java应用程序会产生zombie进程,需要重启其父进程来处理。当然这种问题还是交给研发才能够彻底解决,重启只是权宜之计。
1.僵尸进程是什么?
Linux中,子进程先于父进程结束后并不会消失,而是会在进程表内留下结束信息等待父进程回收,从子进程结束到被父进程回收的这段时间它们成为僵尸进程。
2.为什么要设计僵尸进程
子进程返回结束以后其占用的资源要被回收,内核会将这些子进程转换为僵尸进程来释放他们所占用的大部分资源,这些僵尸进程唯一保留的是内核进程表的一条记录,包括子进程ID,终止状态,资源使用数据等信息。子进程转换为僵尸进程便于其父进程调用wait()来‘认领’这些‘僵尸’并做进一步处理。
3.什么样的情况会导致僵尸进程的产生
子进程结束调用exit()后并不会消失,而是会留下一个存放结束信息的数据结构,直到被父进程调用wait()回收之前,子进程都将处于僵尸状态并保留在进程表中;
一般僵尸进程都能被很快清理掉,但也会出现大量僵尸进程的情况,如僵尸进程的父进程被某事件长期阻塞无法调用wait。
如果子进程在 exit() 之后,父进程没有来得及处理,这时用 ps 命令就能看到子进程的状态是“Z”。如果父进程能及时处理,可能用 ps 命令就来不及看到子进程的僵尸状态,但这并不等于子进程不经过僵尸状态。 如果父进程在子进程结束之前退出,则子进程将由 init 接管。init 将会以父进程的身份对僵尸状态的子进程进行处理。
4.放任僵尸进程不管会有什么危害
僵尸进程只要不被处理,就会永远在内核进程中保留一个位置,如果存在大量此类僵尸进程,他们必会填满内核进程表,从而阻碍新进程的创建。因此僵尸进程的及时清理是有必要的,尤其对于频繁创建大量子进程的程序,如网络服务器。
5.如何杀死僵尸进程
1.一般来说不用特意进行处理,父进程周期性调用wait()或者waitpid()轮询来回收这些进程。
2.对于一直存在的僵尸进程,可以杀死父进程,让init进程来回收称为’孤儿‘的僵尸进程
(比如用任务管理器杀死卡死的软件/电脑死机时重启电脑)
3.在实际情况下,我们如果无法直接杀掉一个僵尸进程,通常找到其父进程将其杀掉,从而干掉该僵尸进程。
ps aux | grep Z
6.孤儿进程是什么
孤儿进程:一个父进程退出,而它的一个或多个子进程还在运行,那么这些子进程将成为孤儿进程。孤儿进程将被 init 进程(进程号为1)所收养,并由 init 进程对它们完成状态收集工作和退出。孤儿进程没有什么危害。