Entendendo e Lidando com Processos Zumbi no Linux
O que é um processo zumbi?
Um processo zumbi é um processo filho que terminou a execução mas ainda tem uma entrada na tabela de processos (código de estado Z, também exibido como [defunct]). O processo em si não está mais executando -- não consome CPU nem memória -- mas seu status de saída ainda não foi coletado pelo processo pai.
$ ps aux | grep Z
USER PID %CPU %MEM VSZ RSS TTY STAT START TIME COMMAND www-data 1234 0.0 0.0 0 0 ? Z 10:01 0:00 [defunct]
O Z na coluna STAT identifica um zumbi.
Por que processos zumbi ocorrem?
A causa raiz é um processo pai que nunca chama wait() ou waitpid() para coletar o status de saída do filho.
Quando um processo termina, o kernel armazena seu status de saída na tabela de processos e envia SIGCHLD ao pai. A entrada permanece lá até o pai recuperar o status. Se o pai nunca o faz, o filho se torna um zumbi permanente.
Causas comuns:
- O pai ignora
SIGCHLDsem configurar coleta automática - O pai tem um bug no seu handler de sinal
- O pai está travado e não consegue processar sinais
Você não pode matar um zumbi com kill -9 -- o processo já está morto. Apenas o pai (ou seu desaparecimento) pode fazer um zumbi desaparecer.
Como detectar zumbis
Encontrar zumbis e seu pai
$ ps -el | grep Z
F S UID PID PPID C PRI NI ADDR SZ WCHAN TTY TIME CMD 4 Z 1000 1234 1100 0 80 0 - 0 - pts/0 00:00:00 process
A coluna PPID mostra o PID do pai (1100 neste exemplo). Confirme o pai com:
$ ps aux | awk 'NR==1 || $2==1100'
Monitorar contagem de zumbis com top
$ top
Tasks: 142 total, 1 running, 141 sleeping, 0 stopped, 2 zombie
Uma contagem de zumbis crescendo constantemente indica um bug continuo em um processo pai.
Como corrigir processos zumbi
Opção 1: sinalizar o pai com SIGCHLD
Se o pai pode lidar com SIGCHLD, enviar o sinal pode fazê-lo chamar wait() e coletar o zumbi.
$ kill -SIGCHLD <PPID>
Opção 2: encerrar o processo pai
Quando o pai termina, o novo pai do zumbi se torna init (PID 1) ou systemd, que o coleta imediatamente.
$ kill <PPID>
Se o pai não responde:
$ kill -9 <PPID>
Antes de forçar o encerramento de um pai que é um serviço (nginx, mysqld, etc.), avalie o impacto nas conexões dependentes e na integridade dos dados.
Opção 3: reiniciar o sistema
Um último recurso quando zumbis se acumularam a um nível que prejudica a operação normal. Um reboot reinicializa a tabela de processos.
Processos zumbi são perigosos?
Alguns poucos zumbis não causam dano real. Eles não consomem CPU nem memória.
Porém, eles se tornam um problema em escala:
- Esgotamento de PID: O teto padrão de PID do Linux (
/proc/sys/kernel/pid_max) é 32.768. Se zumbis se acumulam, os PIDs disponíveis se esgotam e novos processos não podem iniciar. - Pressão na tabela de processos: Cada entrada consome uma pequena quantidade de memória do kernel.
Verifique seu limite de PID atual:
$ cat /proc/sys/kernel/pid_max 32768
Prevenindo processos zumbi no código da aplicação
Zumbis são um sintoma de um bug na aplicação pai. A correção real pertence ao código.
- Chame
waitpid(-1, NULL, WNOHANG)em um loop dentro de um handlerSIGCHLD - Use a técnica de double fork para orfanar o neto sob
init - Defina
SIGCHLDcomoSIG_IGN-- sistemas compatíveis com POSIX fazem a coleta automática dos filhos