Предположим, что я хочу завершить процесс на машине Linux с помощью swap (который на самом деле является zram). Swap занимает половину размера RAM. В RAM всего 10% свободного места, а swap тоже почти заполнен.
Процесс использует всего 2% оперативной памяти, но около 90% подкачки.
Выполнение мягкого закрытия (SIGTERM) и разрешение процессу перехватить сигнал и завершиться самостоятельно приведет к отмене обмена всеми замененными сопоставлениями, но для всего процесса недостаточно свободной оперативной памяти.
Из-за этого, возможно, лучше завершить процесс с помощью SIGKILL, но я все еще опасаюсь, что OOM-killer завершит другие процессы или даже всю сессию X или init из-за нехватки памяти.
Так заставляет ли отправка сигнала kill ядро перемещать выгруженные части процесса в физическую память?(Чего ожидать? Зависит ли это от версии ядра?)
Если да, то что делать в таком случае? Цель — завершить процесс, не трогая остальные (есть другие важные процессы).
Более того, как правильно завершить его, если это не один процесс, а дерево процессов, и я не могу позволить приложению завершиться самостоятельно?
решение1
Вообще говоря, страницы не выгружаются обратно в ОЗУ, если они не нужны. То есть страница будет загружена обратно в ОЗУ только в том случае, если к ней действительно кто-то обращается (вызывая исключение ошибки страницы в MMU, которое ОС обработает, загрузив страницу обратно в ОЗУ, прежде чем разрешить потоку, осуществляющему доступ, продолжить работу). Жесткое завершение процесса (с помощью SIGKILL) не запускает ни один из потоков процесса, поэтому завершенный процесс не может попытаться получить доступ ни к одной из своих страниц, и эти страницы не должны загружаться в ОЗУ.
Фактически, даже если вы не убьете процесс и он возобновит работу, он все равно выгрузит (в ОЗУ) только те страницы, к которым он фактически обращается. Более того, если вся ОЗУ заполнена и ему нужно обратиться к другой странице, которой нет в ОЗУ, ОС выберет другую страницу ОЗУ для выгрузки (на диск), чтобы освободить место в ОЗУ для страницы, к которой нужна ваша программа. Пока в разделе подкачки на диске есть немного места, эта подкачка страниц может продолжаться бесконечно, поддерживая все в рабочем состоянии, не вызывая OOM killer. Конечно, если это происходит часто, это может действительно замедлить вашу машину, потому что большую часть времени она тратит на перемещение памяти между ОЗУ и диском вместо выполнения программных инструкций. Это называется «пробуксовка».
решение2
Что касается уничтожения всего дерева процессов, вы можете попробовать это:
# in pid is saved pid of the parent process
CPIDS=`pgrep -P $pid` # gets pids of child processes
for cpid in $CPIDS ; do kill -9 $cpid ; done # first kill children
kill -9 $pid # then the parent (yeah, that sound kinda bad)