OOM убийца не работает?

41

Насколько я понимаю, когда система близка к отсутствию свободной памяти, ядро ​​должно начать уничтожать процессы, чтобы восстановить часть памяти. Но в моей системе этого не происходит вообще.

Предположим, что простой скрипт просто выделяет гораздо больше памяти, чем доступно в системе (например, массив с миллионами строк). Если я запускаю такой скрипт (как обычный пользователь), он просто получает всю память, пока система полностью не зависнет (работает только SysRQ REISUB).

Странная часть здесь в том, что когда компьютер зависает, светодиод жесткого диска включается и остается таким до перезагрузки компьютера, либо если у меня установлен раздел подкачки, либо нет!

Итак, мои вопросы:

  1. Это нормальное поведение? Странно, что приложение, выполненное как обычный пользователь, может просто так сбить систему ...
  2. Есть ли способ заставить Ubuntu просто автоматически убивать эти приложения, когда они получают слишком много (или больше) памяти?

Дополнительная информация

  • Ubuntu 12.04.3
  • Ядро 3.5.0-44
  • Оперативная память: ~ 3,7 ГБ из 4 ГБ (используется совместно с графической картой). *

    $ tail -n+1 /proc/sys/vm/overcommit_*
    ==> /proc/sys/vm/overcommit_memory <==
    0
    
    ==> /proc/sys/vm/overcommit_ratio <==
    50
    
    $ cat /proc/swaps
    Filename                Type        Size    Used    Priority
    /dev/dm-1                               partition   4194300 344696  -1
    
Salem
источник
Я не уверен, почему это не работает. Попробуйте tail -n+1 /proc/sys/vm/overcommit_*добавить вывод. Смотрите здесь также: Как мне настроить oom-killer
kiri
Так что же происходит с вашим пространством подкачки? Можете ли вы опубликовать какой-нибудь вывод vmstat, например #vmstat 1 100 или что-то в этом роде? а также покажите нам cat / etc / fstab. Что должно произойти, при определенном объеме использования памяти, вы должны начать писать в swap. Процессы уничтожения не должны происходить до тех пор, пока память и пространство подкачки не заполнятся.
j0h
также попробуйте #swapon -a
j0h
@ j0h С swap это работает хорошо (через некоторое время процесс завершился чем-то вроде Allocation failed). Но без свопа просто зависает компьютер. Он должен работать таким образом (убивать только при использовании свопа)?
Салем
2
С SysRq вы также можете вызывать OOM (SysRq + F iirc)
Лекенштейн

Ответы:

36

Из официальной /proc/sys/vm/*документации :

oom_kill_allocating_task

Это включает или отключает уничтожение задачи запуска OOM в ситуациях нехватки памяти.

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

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

Если выбран panic_on_oom, он имеет приоритет над тем значением, которое используется в oom_kill_allocating_task.

Значением по умолчанию является 0.

Для того , чтобы подвести итоги, при установке oom_kill_allocating_taskв 1, вместо сканирования системы в поисках процессов , чтобы убить, что является дорогой и медленной задачей, ядро будет просто убить процесс, вызвавшую систему , чтобы выйти из памяти.

Исходя из моего собственного опыта, когда запускается OOM, ядру больше не хватает «силы» для такого сканирования, что делает систему полностью непригодной для использования.

Кроме того, было бы более очевидно просто убить задачу, вызвавшую проблему, поэтому я не понимаю, почему она установлена 0по умолчанию.

Для тестирования вы можете просто написать соответствующий псевдофайл в файле /proc/sys/vm/, который будет отменен при следующей перезагрузке:

echo 1 | sudo tee /proc/sys/vm/oom_kill_allocating_task

Для постоянного исправления напишите следующее в /etc/sysctl.confили в новый файл /etc/sysctl.d/с .confрасширением ( /etc/sysctl.d/local.confнапример):

vm.oom_kill_allocating_task = 1
Тереза ​​и Джуниор
источник
2
Всегда ли он был равен 0 в Ubuntu? Потому что я помню, что раньше он убивал автоматически, но с нескольких версий он перестал это делать.
скерит
1
@skerit Это я действительно не знаю, но в ядрах, которые я использовал в 2010 году (Debian, Liquorix и GRML), было установлено значение 0.
Тереза ​​и Джуниор
«Кроме того, было бы более очевидно просто убить задачу, вызвавшую проблему, поэтому я не понимаю, почему она установлена 0по умолчанию». - потому что процесс, который запрашивал память, не обязательно тот, который «вызвал проблему». Если процесс A забирает 99% системной памяти, но процесс B, который использует 0,9%, оказывается тем, который запускает убийцу OOM по несчастью, B не «вызывает проблему», и нет смысла kill B. Имея это в качестве политики, вы рискуете полностью беспроблемными процессами с нехваткой памяти случайно быть убитыми из-за использования неконтролируемой памяти другим процессом.
Марк Амери
1
@MarkAmery Реальная проблема заключается в том, что Linux, вместо того, чтобы просто убивать необходимый процесс, начинает работать, как тормоз, даже если его размер vm.admin_reserve_kbytesувеличивается, скажем, до 128 МБ . vm.oom_kill_allocating_task = 1Кажется, установка облегчает проблему, но не решает ее (а Ubuntu по умолчанию уже работает с вилочными бомбами).
Teresa e Junior
1
Может быть, более элегантноsudo sysctl -w vm.oom_kill_allocating_task=1
Пабло
9

Обновление: ошибка исправлена.

Ответа Терезы достаточно, чтобы обойти проблему, и он хороший.

Кроме того, я подал отчет об ошибке, потому что это определенно нарушенное поведение.

int_ua
источник
Я не знаю, почему за вас проголосовали, но это также звучит для меня как ошибка ядра. Сегодня я разбил большой университетский сервер и убил несколько процессов, которые работали в течение нескольких недель ... Спасибо за публикацию этого сообщения об ошибке!
shapecatcher
7
Возможно, это было исправлено в 2014 году, в 2018 году (и 18.04) убийца OOM снова ничего не делает.
скерит
0

Вы можете попробовать Earlyoom , убийцу OOM, который работает в пространстве пользователя и пытается уничтожить самый большой процесс в ситуации OOM.

qwr
источник
-1

Прежде всего, я рекомендую обновить до 13.10 (чистая установка, сохранить ваши данные).

Если вы не хотите обновлять, измените vm.swappiness на 10, и если вы обнаружите проблемы с вашей оперативной памятью, установите zRAM.

Браск
источник
2
Я не был тем, кто отказался от вас, но в целом снижение vm.swappinessприносит больше вреда, чем пользы, даже больше в системах, страдающих от недостатка памяти.
Тереза ​​и Джуниор
Не тогда, когда вы сначала сжимаете оперативную память, а затем избегаете использования диска, которое намного медленнее и может привести к зависанию компьютера.
Браск
Теоретически, zRAM - это хорошая вещь, но она требует много ресурсов процессора и, как правило, не стоит затрат. Память, как правило, намного дешевле, чем электричество. И на ноутбуке, где обновление ОЗУ обходится дороже, загрузка ЦП в основном нежелательна.
Тереза ​​и младший
Он просит иметь более стабильную систему zRAM, и изменение перестановки заставит его систему использовать больше ресурсов ЦП, да, но то, что он ограничен и имеет ошибки, - это память, он хочет решить проблему, а не теоретический урок о том, что происходит при установке zRAM.
Браск
Из его вопроса ясно, что он может написать неправильный сценарий, который ест больше, чем должен (а я уже сделал это сам). В такой ситуации вы можете наблюдать, как сценарий захватывает гигабайты оперативной памяти за несколько секунд, и zRAM не придет на помощь, поскольку сценарий никогда не будет достаточно удовлетворен.
Тереза ​​и Джуниор