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

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

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

3 ответа

Решение

От официального /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

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

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

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

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

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

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

Другие вопросы по тегам