Гид по технологиям

Как найти и убрать zombie‑процессы в Linux

7 min read Linux Обновлено 12 Dec 2025
Как найти и убрать zombie‑процессы в Linux
Как найти и убрать zombie‑процессы в Linux

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

Изображение интерфейса top, показывающего количество zombie процессов

Что такое 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‑процессы (практика)

Используйте встроенные утилиты. Примеры команд — запускать от пользователя с правами, достаточными для просмотра процессов.

  1. top — быстрый обзор
top

Вверху интерфейса top покажет количество зомби процессов (например: Zomb: 3). В списке также можно увидеть строки со статусом Z.

  1. ps + egrep — классический способ
ps aux | egrep "Z|defunct"

Команда ищет строки, где в столбце STAT встречается Z или в командной строке — слово defunct.

  1. ps с выбором полей
ps -eo pid,ppid,stat,cmd | egrep " Z"
  1. /proc — детальный метод
cat /proc//status | grep State

Если статус = Z (zombie) — процесс действительно дефунктивен.

  1. pstree — показывает дерево процессов и defunct‑дети
pstree -p | grep defunct
  1. lsof / proc — редко нужно, но помогает связать PID с ресурсами
lsof -p 

Совет: в скриптах для обнаружения используйте комбинацию ps + awk/grep и отправляйте оповещения при росте числа Z.

Как «убить» zombie‑процесс — методы

Важно: вы не можете убить сам зомби напрямую, потому что он уже завершён. Нужно воздействовать на родителя — заставить его принять завершение дочернего или перезапуститься.

  1. Попробовать заставить родителя принять статус (без его убийства)
# отправить сигнал SIGCHLD родителю, чтобы он попытался собрать дочерние
sudo kill -SIGCHLD 

Если родитель корректно обрабатывает SIGCHLD, он вызовет wait() и очистит зомби.

  1. Убить родителя (если безопасно)
sudo kill -SIGKILL 

После смерти родителя дочерние процессы обычно переходят в состояние orphan и будут приняты init/systemd (PID 1). Затем инициализатор должен выполнить reaping — удалить записи о зомби.

  1. Перезапустить службу через systemd (предпочтительно для демонов)
sudo systemctl restart myservice.service

Это безопаснее, чем убивать процессы вручную, поскольку systemd корректно останавливает и поднимает сервис, а также перезапускает обработчики.

  1. Перезагрузка системы

Полный перезапуск убирает все записи в таблице процессов. Используйте, если нельзя устранить корень проблемы или если много зомби мешают работе.

  1. Отладка и исправление кода (для разработчиков)

Если вы пишете приложение, исправьте поведение: используйте 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 зомби должен очиститься автоматически.

Когда стандартные меры не помогают — возможные причины и обходные пути

  1. Родитель — PID 1 (systemd/init). Если init не убирает зомби, это может указывать на проблему в systemd или в службе. Решение: перезапустить проблемную службу, проверить журналы (journalctl), при необходимости — перезагрузка хоста.

  2. Родитель «завис» внутри ядра (sleep in D). Если родитель не реагирует на сигналы, попробуйте выяснить, в чём блокировка (strace, dmesg). Иногда помогает безопасная перезагрузка.

  3. Kernel‑bug или утечка в подсистеме. В таких случаях нужно собрать дампы, журналы и обратиться к баг‑репорту ядра.

  4. Отладка: прикрепиться через 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 — быстрый план действий

  1. Оценка: сколько дефектных процессов? Какие PPID у них?
  2. Безопасная попытка: sudo kill -SIGCHLD
  3. Если не помогло — аккуратно перезапустить соответствующую службу (systemctl restart), следя за SLA.
  4. Если перезапуск службы невозможен и зомби множатся — плановая перезагрузка хоста.
  5. Пост‑мортем: проанализировать логи, исправить код или конфигурацию, добавить мониторинг.

Критерии приёмки (как убедиться, что проблема решена)

  • Количество процессов в состоянии 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‑процессы — симптом, а не всегда болезнь: часто это признак ошибки в управлении процессами. Для минимизации проблем применяйте простой рабочий процесс:

  1. Наблюдайте (top/ps/pstree). 2) Попробуйте мягко собрать зомби (SIGCHLD). 3) Перезапустите службу безопасно через systemd, если нужно. 4) Если системно — исправляйте код или планируйте реаботацию/перезагрузку.

Если вы системный администратор — автоматизируйте обнаружение и оповещения. Если вы разработчик — убедитесь, что ваше приложение корректно обращается с дочерними процессами.

Краткое резюме: зомби самому убить нельзя — нужно убрать причину (родителя) или заставить родителя сделать reaping. Часто достаточно перезапустить службу, но для долгосрочного решения требуется исправить код или конфигурацию.

Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Отключить клавиатуру ноутбука — безопасные способы
Руководства

Отключить клавиатуру ноутбука — безопасные способы

Oxygen‑GTK: сделать GNOME похожим на KDE
Linux

Oxygen‑GTK: сделать GNOME похожим на KDE

Как пользоваться Lychee Slicer для resin‑3D печати
3D-печать

Как пользоваться Lychee Slicer для resin‑3D печати

Обновление Nexus вручную через заводские образы
Android.

Обновление Nexus вручную через заводские образы

GitHub Copilot в Visual Studio — быстрое руководство
Разработка

GitHub Copilot в Visual Studio — быстрое руководство

Как отключить уведомления на iPhone
iPhone

Как отключить уведомления на iPhone