hostprofi.ru
Подобрать хостинг
Термин·буква З

Зомби-процесс

краткое определение

Зомби-процесс (zombie process) в Linux — завершённый дочерний процесс, запись о котором остаётся в таблице процессов до тех пор, пока родительский процесс не считает его код завершения через системный вызов wait().

Зомби-процесс (zombie, defunct) — процесс, который завершил выполнение, освободил все ресурсы (память, файловые дескрипторы), но его запись всё ещё присутствует в таблице процессов ядра. Состояние обозначается как Z в выводе ps aux или как <defunct> в top. Зомби не потребляет CPU или RAM, но занимает PID — ценный ресурс ограниченного размера.

Как возникает

Механизм появления зомби:

  1. Родительский процесс (parent) создаёт дочерний (fork()).
  2. Дочерний процесс завершается и отправляет сигнал SIGCHLD родителю.
  3. Родитель должен вызвать wait() или waitpid() для считывания exit-статуса дочернего процесса.
  4. Если родитель не вызывает wait() (занят, содержит баг, игнорирует SIGCHLD) — запись дочернего процесса остаётся в таблице как зомби.

Единственная информация, которую ядро хранит в зомби-записи — PID, UID, exit-статус и время CPU.

Как обнаружить: ps aux | grep Z или ps aux | awk '$8=="Z" {print $0}'. Количество зомби: cat /proc/loadavg | awk '{print $4}' (формат X/Y, где Y — общее число процессов, X — runnable).

Как удалить

Убить зомби напрямую (kill -9 <pid>) невозможно — процесс уже мёртв. Методы устранения:

  • Отправить SIGCHLD родителю: kill -SIGCHLD <ppid> — родитель может обработать накопившиеся сигналы и вызвать wait().
  • Убить родительский процесс: при гибели родителя все его дочерние зомби усыновляет init (PID 1), который немедленно вызывает wait() и очищает их из таблицы.
  • Перезагрузить сервер: если родитель — сам init или критический демон, хард-ребут — единственный вариант.

История

Термин "zombie process" появился в ранних версиях Unix (Bell Labs, 1970-е). Назван по аналогии с зомби из фольклора: тело (запись в таблице) существует, но жизни (ресурсов) нет. Механизм wait()/SIGCHLD описан в стандарте POSIX. Проблема зомби актуальна при разработке серверных приложений, использующих fork() без правильной обработки SIGCHLD.

На что обращать внимание

Несколько зомби — норма и не опасно. Сотни или тысячи зомби истощают пространство PID (по умолчанию max_pid = 32768 в Linux 32-bit, 4194304 в 64-bit). При исчерпании PID ни один новый процесс запустить невозможно — сервер фактически перестаёт работать. Для серверных приложений на C/C++ используйте sigaction(SIGCHLD, SA_NOCLDWAIT) или двойной fork() для предотвращения зомби. В PHP, Python, Node.js — следите за правильным завершением дочерних процессов в пулах воркеров (PHP-FPM, multiprocessing).

История и природа зомби-процессов

Концепция zombie-процесса появилась в Unix с момента создания модели процессов (Bell Labs, 1969). Первое упоминание термина «zombie» в контексте процессов — Version 7 Unix (1979), страница man ps. Зомби не потребляют CPU или память, но занимают запись в таблице процессов ядра. Максимум процессов в Linux определяется /proc/sys/kernel/pid_max (по умолчанию 32768 или 4194304 на 64-bit). Накопление тысяч зомби исчерпывает PID-пространство.

Почему возникают зомби-процессы

Зомби появляются когда: родительский процесс не вызывает wait() или waitpid() для считывания exit-статуса дочернего. Баги в коде приложений — частая причина. Zombie-процессы удаляются автоматически после гибели родителя (init/systemd усыновляет и «пожинает» их). Команды диагностики:

ps aux | grep Z     # найти зомби (stat = Z)
ps -eo ppid,pid,stat,comm | grep Z  # с PPID родителя
kill -SIGCHLD $(ppid)               # сигнал родителю для очистки

На хостинге: когда зомби — проблема

На VPS с PHP-FPM: зомби возникают при неправильной конфигурации pm = dynamic с высоким max_children. В Docker: используйте --init флаг (tini) — он правильно управляет дочерними процессами. Мониторинг количества зомби через Zabbix или Prometheus node_exporter (метрика node_processes_state{state="Z"}).

Типичные ошибки

  • Попытка убить зомби через kill -9 PID — не работает, зомби уже мёртв.
  • Игнорирование роста числа зомби — признак утечки в родительском процессе.
  • Перезагрузка сервера как метод борьбы с зомби — только маскирует проблему в коде.

Другие термины