Мертвые, но не ушедшие: как победить зомби-процессы в Linux
Представьте, что в недрах вашей системы притаились цифровые зомби. Они не выполняют никакой полезной работы, но продолжают занимать ценные ресурсы. Это не сценарий хоррора, а реальная проблема, с которой сталкивается каждый администратор Linux.
Речь идет о зомби-процессах. Это не ошибка, а особенность работы операционной системы. Когда дочерний процесс завершает свою работу, он должен сообщить об этом родителю. Но если родитель по какой-то причине не получает это сообщение, процесс превращается в «зомби».
Он уже мертв, но система продолжает хранить о нем запись. Вы не можете убить его даже мощнейшим сигналом `SIGKILL` – он просто неуязвим. Эти процессы, помеченные как `defunct`, висят в памяти, захламляя таблицу процессов.
Как их обнаружить? Все просто: одной командой `ps aux | grep defunct` вы увидите всю нежить в вашей системе. Но что делать дальше? Силовой метод не сработает. Секрет в том, чтобы найти и "убить" не самого зомби, а его родителя.
Именно родительский процесс держит своего ребенка в этом подвешенном состоянии. Узнав его идентификатор (PPID), вы одним точным сигналом `kill` сможете очистить систему от всей нежелательной компании.
Хотите навсегда избавиться от этих призраков и понять механизм их появления? В этой статье вы найдете пошаговое руководство по выявлению и ликвидации зомби-процессов. Мы разберем все на практических примерах, чтобы вы больше никогда не боялись увидеть в своей системе пометку `defunct`.
Каждая программа, которая выполняется в Linux, - это системный процесс, у которого есть свой идентификатор. Каждый процесс может запускать дочерние процессы с помощью функции fork. Такие процессы остаются под контролем родительского процесса и не могут быть завершены без его ведома. Если один из дочерних процессов всё же завершился, а его родительский процесс не смог получить об этом информацию, то такой дочерний процесс становится зомби.
Зомби процессы Linux не выполняются и убить их нельзя, даже с помощью sigkill, они продолжают висеть в памяти, пока не будет завершён их родительский процесс.
Посмотреть такие процессы можно с помощью утилиты ps, здесь они отмечаются как defunct:
ps aux | grep defunct
Если вы попытаетесь убить такой процесс с помощью сигнала KILL, то ничего не выйдет:
Чтобы его завершить, нужно найти "родителя" этого процесса. Для этого используйте команду:
ps -xal | grep defunct
Здесь идентификатор родительского процесса находится в четвёртой колонке (PPID). Теперь мы можем послать ему сигнал завершения, и такого процесса в системе больше не будет:
kill -KILL 3990
Для большего удобства вы можете использовать утилиты top или htop, но принцип их действия будет аналогичным, поэтому я не буду здесь его рассматривать. Теперь вы знаете, что делать, если в вашей системе появились зомби процессы Linux.