Как найти и убрать zombie‑процессы в Linux
Важно: одиночные зомби обычно безвредны. Массовые «defunct» могут исчерпать доступные PID и нарушить работу сервера.

Что такое zombie‑процессы
Zombie‑процесс (иногда пишут «зомби» или defunct) — это процесс, который уже завершил выполнение, но его запись в таблице процессов (и связанные с ней метаданные, PCB) не были освобождены, потому что родительский процесс не считаёт статус завершения дочернего при помощи wait()/waitpid().
Коротко: процесс выполнил работу, память и ресурсы освобождены, но запись о нём осталась в таблице процессов. У каждого зомби остаётся PID — он не доступен для повторного использования до удаления записи.
1‑строчное определение: зомби — это завершённый процесс, чей PID и запись в таблице процессов ещё не удалены, потому что родитель не вызвал reaping (wait).
Почему это происходит (основные причины)
- Родительский процесс не вызывает wait()/waitpid() после завершения дочернего. Это частая ошибка в пользовательском коде.
- Родитель завис или блокируется и не реагирует на SIGCHLD, поэтому не может собрать статус дочернего.
- Неправильная реализация демона/службы (например, не использует double‑fork или корректную обработку SIGCHLD).
- Специальные случаи: если родительом является PID 1 (systemd или init), поведение зависит от инициализатора — он должен принимать и очищать зомби; если этого не происходит, нужен перезапуск init‑службы или ядра.
- Редко: баги в ядре или в подсистемах, которые мешают корректному освобождению таблицы процессов.
Ключевые состояния процессов
Linux кодирует состояния процессов метками. Часто используемые:
- R — выполняется (running)
- S — спит (sleeping)
- D — uninterruptible sleep
- T — остановлен или трассируется
- Z — zombie / defunct
Где хранятся данные о процессе (коротко)
Process Control Block (PCB) содержит: PID, состояние, счётчик команд (program counter), регистры, список открытых файлов, информацию о планировщике, управление памятью, I/O‑информацию и др. Зомби сохраняют часть этой информации в таблице, пока не будут «сняты» родителем.
Как найти zombie‑процессы (практика)
Используйте встроенные утилиты. Примеры команд — запускать от пользователя с правами, достаточными для просмотра процессов.
- top — быстрый обзор
topВверху интерфейса top покажет количество зомби процессов (например: Zomb: 3). В списке также можно увидеть строки со статусом Z.
- ps + egrep — классический способ
ps aux | egrep "Z|defunct"Команда ищет строки, где в столбце STAT встречается Z или в командной строке — слово defunct.
- ps с выбором полей
ps -eo pid,ppid,stat,cmd | egrep " Z"- /proc — детальный метод
cat /proc//status | grep State Если статус = Z (zombie) — процесс действительно дефунктивен.
- pstree — показывает дерево процессов и defunct‑дети
pstree -p | grep defunct- lsof / proc — редко нужно, но помогает связать PID с ресурсами
lsof -p Совет: в скриптах для обнаружения используйте комбинацию ps + awk/grep и отправляйте оповещения при росте числа Z.
Как «убить» zombie‑процесс — методы
Важно: вы не можете убить сам зомби напрямую, потому что он уже завершён. Нужно воздействовать на родителя — заставить его принять завершение дочернего или перезапуститься.
- Попробовать заставить родителя принять статус (без его убийства)
# отправить сигнал SIGCHLD родителю, чтобы он попытался собрать дочерние
sudo kill -SIGCHLD Если родитель корректно обрабатывает SIGCHLD, он вызовет wait() и очистит зомби.
- Убить родителя (если безопасно)
sudo kill -SIGKILL После смерти родителя дочерние процессы обычно переходят в состояние orphan и будут приняты init/systemd (PID 1). Затем инициализатор должен выполнить reaping — удалить записи о зомби.
- Перезапустить службу через systemd (предпочтительно для демонов)
sudo systemctl restart myservice.serviceЭто безопаснее, чем убивать процессы вручную, поскольку systemd корректно останавливает и поднимает сервис, а также перезапускает обработчики.
- Перезагрузка системы
Полный перезапуск убирает все записи в таблице процессов. Используйте, если нельзя устранить корень проблемы или если много зомби мешают работе.
- Отладка и исправление кода (для разработчиков)
Если вы пишете приложение, исправьте поведение: используйте waitpid(), обработчик SIGCHLD или шаблон double‑fork для демонов, чтобы избежать накопления зомби.
Код‑пример шаблона приёма дочерних (сниппет на С):
// упрощённый обработчик SIGCHLD
void sigchld_handler(int signo) {
while (waitpid(-1, NULL, WNOHANG) > 0) {}
}Примеры команд из статьи (переведённые и пояснённые)
Найти PID родителя для зомби (замените 18614 на ваш PID):
ps -o ppid= -p 18614Проверить, существует ли родитель:
ps -e | grep 18613Забить родителя принудительно:
sudo kill -SIGKILL 18613После этого PID зомби должен очиститься автоматически.
Когда стандартные меры не помогают — возможные причины и обходные пути
Родитель — PID 1 (systemd/init). Если init не убирает зомби, это может указывать на проблему в systemd или в службе. Решение: перезапустить проблемную службу, проверить журналы (journalctl), при необходимости — перезагрузка хоста.
Родитель «завис» внутри ядра (sleep in D). Если родитель не реагирует на сигналы, попробуйте выяснить, в чём блокировка (strace, dmesg). Иногда помогает безопасная перезагрузка.
Kernel‑bug или утечка в подсистеме. В таких случаях нужно собрать дампы, журналы и обратиться к баг‑репорту ядра.
Отладка: прикрепиться через gdb или использовать strace, чтобы увидеть, почему родитель не вызывает wait().
Профилактика: как не допустить появления зомби
- Для демонов используйте надёжный шаблон демонизации (double‑fork) или управляйте дочерними через systemd‑таймеры/сервисы.
- В коде: всегда проверяйте и обрабатывайте SIGCHLD, используйте waitpid() с WNOHANG в цикле.
- Для скриптов: избегайте фонового порождения большого числа дочерних без их контроля.
- Мониторинг: настраивайте алерты, если количество процессов со статусом Z превышает порог (например, >10).
Роль‑ориентированные чеклисты
Для администратора (операции):
- Найти и перечислить все Z (ps/pstree/top).
- Определить PPID для каждого зомби.
- Оценить риски убийства PPID (завершится ли важная служба?).
- Попробовать отправить SIGCHLD родителю.
- Если безопасно — перезапустить системную службу через systemctl.
- Если нет — плановый перезапуск хоста.
Для разработчика (аппликейшн):
- Проверить обработку SIGCHLD.
- Убедиться, что используется waitpid() при порождении дочерних.
- Рассмотреть внедрение supervisor/systemd unit вместо фоновых скриптов.
- Написать интеграционные тесты, имитирующие завершение дочерних.
Инцидентный runbook — быстрый план действий
- Оценка: сколько дефектных процессов? Какие PPID у них?
- Безопасная попытка: sudo kill -SIGCHLD
- Если не помогло — аккуратно перезапустить соответствующую службу (systemctl restart), следя за SLA.
- Если перезапуск службы невозможен и зомби множатся — плановая перезагрузка хоста.
- Пост‑мортем: проанализировать логи, исправить код или конфигурацию, добавить мониторинг.
Критерии приёмки (как убедиться, что проблема решена)
- Количество процессов в состоянии Z равно нулю в течение наблюдаемого окна (например, 10 минут).
- PID‑таблица не приближается к лимиту (ulimit -u) и не наблюдаются ошибки «cannot fork».
- Сервис функционирует: ключевые endpoint‑ы возвращают 2xx/3xx коды и задержки в норме.
Отладочные приёмы и проверки
- journalctl -u
-f — смотреть логи службы при перезапуске. - strace -p
— понять, что мешает родителю вызвать wait(). - cat /proc/
/status — проверить State и Parent. - grep Z /proc/*/status — найти все процессы со статусом Z (не для регулярного использования на больших системах, дорого).
Простая автоматизация (шаблон скрипта)
#!/bin/bash
# Найти и вывести зомби
ps -eo pid,ppid,stat,cmd | awk '$3 ~ /Z/ {print}
'Такой скрипт удобно запускать по cron и отправлять отчёт на почту или в систему мониторинга.
Когда не стоит беспокоиться: контрпримеры
- Одиночный зомби в десктопной среде, который появляется и сразу исчезает — это нормально.
- Некритичные фоновые утилиты иногда оставляют кратковременные defunct записи — не мешают работе.
Короткая памятка для разработчиков (чек‑лист)
- Всегда обрабатывайте SIGCHLD.
- Используйте waitpid() с WNOHANG.
- Для демонов применяйте проверенные шаблоны демонизации.
- Тестируйте сценарии завершения дочерних процессов.
Короткий глоссарий (1‑строчные определения)
- PID: идентификатор процесса.
- PPID: идентификатор родительского процесса.
- PCB: структура данных, описывающая процесс.
- Reaping: действия по удалению записи о завершённом процессе.
- Defunct / Zombie: процесс, завершившийся, но остающийся в таблице процессов.
Итог и рекомендации
Zombie‑процессы — симптом, а не всегда болезнь: часто это признак ошибки в управлении процессами. Для минимизации проблем применяйте простой рабочий процесс:
- Наблюдайте (top/ps/pstree). 2) Попробуйте мягко собрать зомби (SIGCHLD). 3) Перезапустите службу безопасно через systemd, если нужно. 4) Если системно — исправляйте код или планируйте реаботацию/перезагрузку.
Если вы системный администратор — автоматизируйте обнаружение и оповещения. Если вы разработчик — убедитесь, что ваше приложение корректно обращается с дочерними процессами.
Краткое резюме: зомби самому убить нельзя — нужно убрать причину (родителя) или заставить родителя сделать reaping. Часто достаточно перезапустить службу, но для долгосрочного решения требуется исправить код или конфигурацию.
Похожие материалы
Отключить клавиатуру ноутбука — безопасные способы
Oxygen‑GTK: сделать GNOME похожим на KDE
Как пользоваться Lychee Slicer для resin‑3D печати
Обновление Nexus вручную через заводские образы
GitHub Copilot в Visual Studio — быстрое руководство