좀비 프로세스
IT 위키
더 많은 작업
- Zombie Process; defunct 프로세스
- 실행을 마치고 종료했지만 부모 프로세스가 종료 상태를 회수(wait)하지 않아 프로세스 테이블에 항목만 남아 있는 자식 프로세스
- 자식 프로세스가 종료하면 커널은 메모리 등 자원을 거두고, 종료 코드와 PID 만 프로세스 테이블에 남긴 뒤 부모에게 SIGCHLD 시그널을 보낸다
- 부모가 wait()·waitpid() 로 종료 상태를 읽어 가야 항목이 지워진다. 부모가 이를 호출하지 않거나 SIGCHLD 를 처리하지 않으면 자식은 Z(좀비) 상태로 남는다
- 즉 좀비는 부모 프로세스의 오류(회수 누락) 때문에 생긴다
| 구분 | 좀비 프로세스 | 고아 프로세스 |
|---|---|---|
| 상태 | 자식이 먼저 종료했는데 부모가 회수하지 않음 | 부모가 먼저 종료했는데 자식은 아직 실행 중 |
| 처리 | 부모가 wait() 하거나, 부모가 끝나면 init(systemd)이 넘겨받아 회수 | init(PID 1, systemd)이 새 부모가 되어 나중에 회수 |
| 자원 | CPU·메모리는 쓰지 않고 PID 와 테이블 항목만 차지 | 정상 프로세스처럼 자원을 씀 |
- 좀비가 많이 쌓이면 PID 가 고갈되어 새 프로세스를 만들 수 없게 된다
- top 명령어를 통해 좀비 프로세스의 수, 좀비 프로세스를 확인할 수 있다.
- 개수: 두번째줄 마지막에 1 zombie를 통해 개수 확인
- 프로세스: 프로세스 목록 중 두번째 S(Status)가 Z로 표시된 프로세스 확인
[root@itwiki ~]# top
top - 22:01:31 up 97 days, 17:08, 1 user, load average: 0.00, 0.00, 0.00
Tasks: 118 total, 3 running, 114 sleeping, 0 stopped, 1 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
Mem: 1048576k total, 990160k used, 58416k free, 180060k buffers
Swap: 2031608k total, 48520k used, 1983088k free, 203936k cached
PID USER PR NI VIRT RES SHR S %CPU %MEM TIME+ COMMAND
1 root 15 0 10368 544 512 S 0.0 0.1 0:00.12 init
2 root RT -5 0 0 0 Z 0.0 0.0 0:03.16 migration/0
3 root 34 19 0 0 0 S 0.0 0.0 0:00.00 ksoftirqd/0
4 root RT -5 0 0 0 S 0.0 0.0 0:00.00 watchdog/0
- 아래와 같은 명령어를 통해 간단히 개수만 확인할 수도 있다.
[root@itwiki ~]# top -b -n 1 | grep zombie Tasks: 139 total, 1 running, 136 sleeping, 0 stopped, 2 zombie
- ps와 grep명령어를 통해 프로세스를 특정해서 조회할 수 있다.
[root@itwiki ~]# ps -ef | grep defunct | grep -v grep root 17107 21899 0 Feb25 ? 00:00:00 [myagent] <defunct> testuser 21207 21205 0 Feb26 ? 00:00:00 [check_service.sh] <defunct>
- 좀비는 이미 종료한 상태라 kill -9 를 보내도 사라지지 않는다. 부모에게 SIGCHLD 를 보내 회수를 유도하거나, 그래도 안 되면 부모 프로세스를 종료해 init 이 회수하게 한다
- 아래 명령어는 ps 결과의 세 번째 열(PPID), 즉 좀비의 부모를 일괄 종료한다. 부모가 중요한 서비스일 수 있으므로 확인한 뒤 쓴다.
ps -ef | grep defunct | awk '{print $3}' | xargs kill -9