Каждая программа, которая выполняется в Linux, — это системный процесс, у которого есть свой идентификатор. Каждый процесс может запускать дочерние процессы с помощью функции fork. Такие процессы остаются под контролем родительского процесса и не могут быть завершены без его ведома. Если один из дочерних процессов всё же завершился, а его родительский процесс не смог получить об этом информацию, то такой дочерний процесс становится зомби.
Зомби процессы Linux не выполняются и убить их нельзя, даже с помощью sigkill, они продолжают висеть в памяти, пока не будет завершён их родительский процесс.
Посмотреть такие процессы можно с помощью утилиты ps, здесь они отмечаются как defunct:
ps aux | grep defunct
Если вы попытаетесь убить такой процесс с помощью сигнала KILL, то ничего не выйдет:
Чтобы его завершить, нужно найти «родителя» этого процесса. Для этого используйте команду:
ps -xal | grep defunct
Здесь идентификатор родительского процесса находится в четвёртой колонке (PPID). Теперь мы можем послать ему сигнал завершения, и такого процесса в системе больше не будет:
kill -KILL 3990
Для большего удобства вы можете использовать утилиты top или htop, но принцип их действия будет аналогичным, поэтому я не буду здесь его рассматривать. Теперь вы знаете, что делать, если в вашей системе появились зомби процессы Linux.
Обнаружили ошибку в тексте? Сообщите мне об этом. Выделите текст с ошибкой и нажмите Ctrl+Enter.
Статья распространяется под лицензией Creative Commons ShareAlike 4.0 при копировании материала ссылка на источник обязательна .
Об авторе
Основатель и администратор сайта losst.ru, увлекаюсь открытым программным обеспечением и операционной системой Linux. В качестве основной ОС сейчас использую Ubuntu. Кроме Linux, интересуюсь всем, что связано с информационными технологиями и современной наукой.
Процесс называется “зомби” или “мертвым” процессом, когда его выполнение завершено, но он все еще может попасть в таблицу процессов.
В идеале такие процессы должны быть удалены из таблицы процессов после завершения их выполнения.
Однако по какой-то причине родительский процесс не удалил его должным образом.
Такие “неработающие” процессы наблюдаются в основном у дочерних процессов.
Как сохранить процессы, запущенные после выхода SSH в Linux
Родительский процесс считывает статус завершения своего дочернего процесса.
Это делается с помощью системного вызова wait().
Как только это сделано, зомби-процесс ликвидируется.
Чтобы лучше понять процесс образования и устранения зомби-процесса, посмотрите приведенную ниже схему.
Содержание
- Как работает состояние зомби-процесса
- Интересные факты о зомби-процессах
- Опасны ли зомби-процессы?
- Как найти и убить зомби-процессы
- Заключение
Как работает состояние зомби-процесса
Итак, как работает состояние зомби-процесса?
В состоянии зомби-процесса родитель вызывает одну функцию wait() во время создания дочернего процесса.
Затем он ждет изменения состояния дочернего процесса.
В случае изменения состояния, при котором дочерний процесс остановился, считывается его код состояния завершения.
После этого PCB (process control block) дочернего процесса уничтожается, а запись очищается.
Это происходит очень быстро, и зомби-процесс существует недолго.
Интересные факты о зомби-процессах
Некоторые интересные факты о зомби-процессах включают:
Вся системная память и другие ресурсы, выделенные зомби-процессу, деаллокируются при его завершении с помощью системного вызова exit().
Но его запись в таблице остается доступной.
Если родительский процесс не запущен, наличие зомби-процесса означает ошибку в операционной системе.
Это может не вызывать серьезных проблем, если зомби-процессов немного.
Но при больших нагрузках присутствие зомби-процессов может привести к нехватке записей в таблице процессов.
Мы рассмотрим опасность зомби-процессов в следующем разделе этой статьи.
Родительский процесс считывает статус завершения зомби-процесса с помощью функции wait().
Затем зомби-процесс удаляется из системы.
После его удаления запись в таблице процессов и идентификатор процесса могут быть использованы повторно.
Если функция wait() не используется родительским процессом, зомби остается в таблице процессов.
Это создает утечку ресурсов.
Послав сигнал SIGCHLD родительскому процессу с помощью команды kill, вы можете удалить зомби-процесс из системы.
Если зомби-процесс остается в таблице процессов даже после отправки сигнала SIGCHLD, родительский процесс должен быть завершен, если это допустимо.
Опасны ли зомби-процессы?
Зомби-процессы используют немного памяти, но обычно они не представляют опасности.
Запись в таблице процессов небольшая, но вы не можете использовать идентификатор процесса, пока зомби-процесс не будет освобожден.
На 64-разрядной ОС это не создаст проблемы, потому что PCB больше, чем запись таблицы процессов.
Огромное количество зомби-процессов может повлиять на свободную память, доступную для других процессов.
Если вы столкнулись со слишком большим количеством зомби-процессов, значит, существует какая-то серьезная проблема с ошибкой операционной системы или родительского приложения.
В этом случае оставшиеся идентификаторы процессов монополизируются зомби.
Если не остается ни одного идентификатора процесса, другие процессы не могут быть запущены.
Как найти и убить зомби-процессы
Чтобы убить зомби-процесс, сначала найдите его.
Используйте приведенные ниже команды для выявления зомби-процессов.
$ ps aux | egrep "Z|defunct"
Z, используемый в колонке STAT, и/или [defunct], используемый в последней колонке вывода, идентифицирует зомби-процесс.
На самом деле, вы не можете убить зомби-процессы, так как они уже мертвы.
Все, что вы можете сделать, это уведомить его родительский процесс, чтобы он мог снова попытаться прочитать статус дочернего процесса, который теперь стал зомби-процессом, и, в конце концов, мертвый процесс будет удален из таблицы процессов.
Используйте следующую команду, чтобы узнать ID родительского процесса.
$ ps -o ppid= <PID дочернего процесса>.
Как только вы узнаете ID родительского процесса зомби, отправьте SIGCHLD родительскому процессу.
$ kill -s SIGCHLD <Родительский PID>.
Если это не помогло удалить зомби-процесс из таблицы процессов, вам нужно перезапустить или убить его родительский процесс.
Чтобы убить родительский процесс зомби, используйте следующий код.
$ kill -9 <Родительский PID>
Побочное замечание: После того как вы убьете родительский процесс, пострадают и его дочерние процессы. Поэтому рекомендуется провести быструю двойную проверку.
Это поможет вам обезопасить себя.
Если наблюдается огромный всплеск существующих зомби-процессов, что приводит к сбою в работе системы или движется к нему, необходимо выполнить перезагрузку системы.
В качестве альтернативы можно предположить, что небольшое количество зомби-процессов не использует много памяти или системных ресурсов.
В этом случае целесообразно перезагрузить или убить родительский процесс в ходе предстоящего планового обслуживания системы.
Заключение
В этой статье вы узнали, как найти и убить зомби-процессы Linux.
Теперь вы знаете, что такое зомби-процесс, как определить зомби-процесс в Linux и удалить его из таблицы процессов.
Мы также вкратце рассмотрели состояния процессов и то, как работает состояние зомби-процесса.
Итак, вывод: зомби не опасны, если их своевременно чистить и обслуживать.
Надеемся, что эта статья оказалась полезной и дала ответы на ваши вопросы, связанные с зомби-процессами в Linux.
Apr 27, 2017 16:22
· 405 words
· 2 minute read
zombie
defunct
Дочерний процесс в Unix-системе, завершивший своё выполнение, но ещё присутствующий в списке процессов операционной системы, чтобы дать родительскому процессу считать код завершения называют зомби (англ. zombie process, defunct process) — говорит нам Википедия.
Подробнее ознакомиться с возникновением зомби-процессов и связанными с ними проблемами можно на той же Wiki, а мы разберемся как вычислить такие процессы и “убить” их!
Найти zombie
-процесс можно несколькими способами, например:
или
или
ps -alx | awk '$10 ~ /STAT|Z/'
Итак, находим zombie
-процессы в нашей системе:
ps aux | grep -w Z
git 2512 0.6 0.0 0 0 ? Z 08:31 1:08 [grunt]
git 3574 0.0 0.0 0 0 ? Z кві13 0:48 [grunt]
root 12523 0.0 0.0 112652 1036 pts/5 S+ 11:22 0:00 grep --color=auto -w Z
git 13855 0.3 0.0 0 0 ? Z 07:07 0:47 [grunt]
git 14896 0.0 0.0 0 0 ? Z кві13 0:48 [grunt]
git 16213 0.0 0.0 0 0 ? Z кві03 0:44 [grunt]
git 24146 0.5 0.0 0 0 ? Z 07:49 1:11 [grunt]
git 26321 0.0 0.0 0 0 ? Z кві13 0:47 [grunt]
git 29765 0.5 0.0 0 0 ? Z 08:10 1:09 [grunt]
git 32440 0.0 0.0 0 0 ? Z кві13 0:47 [grunt]
“Убить” найденные zombie-процессы просто так не получится. Самый правильный вариант — найти родительский процесс и убить или перезапустить его. (Еще может помочь перезагрузка сервера, но это точно не наш путь). Находим родительские процессы (их PID’ы в третьей колонке):
ps ajx | grep -w Z
2475 2512 2427 2427 ? -1 Z 1004 1:08 [grunt]
3557 3574 3509 3509 ? -1 Z 1004 0:48 [grunt]
12350 12671 12671 12330 pts/5 12671 S+ 0 0:00 grep --color=auto -w Z
13839 13855 13791 13791 ? -1 Z 1004 0:47 [grunt]
14869 14896 14820 14820 ? -1 Z 1004 0:48 [grunt]
16192 16213 16144 16144 ? -1 Z 1004 0:44 [grunt]
24120 24146 24071 24071 ? -1 Z 1004 1:11 [grunt]
26290 26321 26236 26236 ? -1 Z 1004 0:47 [grunt]
29725 29765 29645 29645 ? -1 Z 1004 1:09 [grunt]
32423 32440 32375 32375 ? -1 Z 1004 0:47 [grunt]
При желании можно узнать больше подробностей о родительском процессе, например так:
ps auxww | grep 32375
root 12689 0.0 0.0 112648 1016 pts/5 S+ 11:23 0:00 grep --color=auto 32375
git 32375 0.0 0.0 211180 2892 ? Ss кві13 0:00 git-receive-pack /home/git/repo/ed.git
Дальше этот процесс можем просто “убить”:
tweet
Share
Опубликовано 28.12.2021
Если процесс был завершен, но его PID и запись процесса остались в таблице процессов Linux. Зомби процессы Linux возникают если родительский процесс не может вызвать wait (), его дочерний процесс останется в таблице процессов, превратившись в зомби.
Поиск зомби процессов в Linux
Для поиска зависших процессов выполняем следующую команду
ps axo stat,ppid,pid,comm | grep -w defunct
Команда найдет все зависшие в системе процессы
Пример:
Z 42365 679033 httpd <defunct>
Завершить зомби процессы в linux
Есть несколько вариантов попробовать завершить зомби процесс.
Отправить команду SIGCHLD. В данном случае это процесс с PPID 42365
Если зомби процесс все еще не завершен, то можно попробовать завершить родительский процесс
Как только его родительский процесс будет убит, зомби процесс будет завершен init, который является родительским для всех процессов в Linux.
Brief: This is a quick tip on finding zombie processes in Linux and then killing them. You also learn a thing or two about processes and zombie processes.
Before you learn about Zombie process, let me recall what is a process in Linux.
In a few words, a process is a running instance of a program in performance. It can be foreground (interactive process) or background (not interactive or automatic process). It can be a parent (creator of other processes during run-time) or child (process created by others) process.
In Linux, except for the first init (or systemd) process with PID 0, every other process has a parent process. Processes also have their own child processes.
Don’t believe me? Use the pstree
command in terminal to look at the process tree to see the ‘family tree’ of your system’s processes.
What is a Zombie process in Linux?
When a child process dies, the parent process is informed so that it can do some clean up like freeing up memory etc. However, child process goes into zombie state if the parent process is not aware of its death. For the parent, the child still exists but the child process is actually dead. This is how zombie processes (also known as defunct processes) are created and stay in the system.
Here’s an excellent funny take on the zombie process by Turnoff.us:
Do you really need to worry about Zombie processes?
Here is important to say that zombie processes are not as dangerous as its name can sound.
The problem may arise if your system has limited RAM or if there are too many zombie processes eating up RAM. Also, most Linux processes can have maximum PID set to 32768. If there are no available IDs for other productive tasks, your system may crash.
This rarely happens, but it’s a possibility, specially if a poorly coded program starts inducing numerous zombie processes.
In such case, it would be a good idea to find and kill zombie process.
How to find zombie processes?
A process in Linux can have one of the following states:
- D = uninterruptible sleep
- I = idle
- R = running
- S = sleeping
- T = stopped by job control signal
- t = stopped by debugger during trace
- Z = zombie
But where can you see the processes and their respective status? One easy way is to use the terminal and the top command.
As you can see in the screenshot above, there are 250 total tasks (or processes), 1 is running, 248 processes are sleeping and 1 is in zombie state.
Now, the question arises, how to kill the zombie process?
How to find and kill a zombie process? Can a zombie process be killed?
A zombie process is already dead. How do you kill an already dead process?
In the zombie movies, you shoot the zombies in the head or burn it. That’s not an option here. You can burn your system for killing the zombie process but that’s not a feasible solution
Some people suggests sending SIGCHLD signal to the parent process. But it is more likely to be ignored. The other option to kill the zombie process is to kill its parent process. That sounds brutal but that’s the only sure shot way of killing zombie processes.
So, first, let’s list the zombie processes to know their ID. It can be achieved by using the ps command like this in the terminal.
ps aux | awk '$8 ~ /^[Zz]/'
The 8th column in the output of the ps aux command displays the state of a process. You are asking to print all the matching lines where the state of a process starts with Z or z.
Once you have identified its process ID, let’s get its parent’s process ID.
ps -o ppid= -p <child_id>
Alternatively, you can combine the above two commands in the following fashion where it directly provides the PID of the zombie process and the PID of its parent process.
ps -A -ostat,pid,ppid | grep -e '[zZ]'
Here you get the parent process ID, so finally kill the process by typing the command line with its respective ID process obtained before.
kill -9 <parent_process_ID>
You can verify if the zombie process is killed or not by running the ps command again or even the top command.
Congrats! Now you know how to eliminate zombie processes.
With inputs from Abhishek Prakash.