Поведение ядра при высокой загрузке памяти

Я наблюдал следующее поведение под Ubuntu 12.04:

В системе с 24 ГБ ОЗУ и 24 ЦП, если один процесс получает ~12 ГБ ОЗУ, все другие процессы, принадлежащие владельцу процесса с высокой памятью, завершаются без предупреждения, используя, как представляется, SIGKILL, и процесс с высокой памятью. разрешено работать до завершения. Кроме того, попытки запуска новых процессов владельцем не удастся.

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

1 ответ

Решение

Извините, что отвечаю на мой вопрос, но мне нравится иметь список решений. Статья, связанная опилками, содержит то, что мне было нужно.

  • Ядро активирует диспетчер нехватки памяти (mm/oom_kill.c в ядре Linux), когда у него заканчивается выделенная память.
  • Менеджер OOM использует некоторую эвристику, чтобы определить, какой процесс следует убить. Общее время выполнения процесса уменьшает вероятность смерти, а выделенная память увеличивает ее. Есть и другие факторы, но они не имеют значения для меня.
  • После выбора процесса, OOM отправляет его SIGTERM.

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

  1. Мой процесс игнорирует SIGTERM в той области, где он выделяет память. Это может быть связано с тем, что процесс активно принимает множество других сигналов в течение этого времени, и / или потому, что процесс блокирует ввод-вывод в течение большей части оставшегося времени. В любом случае, он игнорирует SIGTERM.

  2. Процесс, занимающий всю память, обычно выполняется в течение длительного времени, накапливая ОЗУ в течение нескольких часов. Несмотря на то, что он имеет примерно в 4 раза больше, чем любой другой процесс, его длительное время выполнения (в несколько сотен раз больше, чем у других) может привести к тому, что диспетчер OOM сначала выберет другие процессы для завершения.

Решения:

  1. Бег:

    ulimit -v memamount

для конкретного пользователя изменяется максимальный объем памяти, который пользователь может выделить с помощью одного процесса на memamount. Это может предотвратить активацию менеджера OOM. Вместо этого вызовы malloc не будут выполнены, что я могу обнаружить.

2: Написание обработчика для SIGTERM, который корректно очищает, может помочь, но только если OOM фактически отправляет SIGTERM процессу, а процесс игнорирует или не получает SIGTERM.

3: Установите предел памяти из вашего кода (C):

//resource limit structure with both hard and soft max set to 2GB.
struct rlimit memmax; memmax.rlim_max=0x7FFFFFFF; memmax.rlim_cur = 0x7FFFFFFF;
setrlimit(RLIMIT_MEMLOCK,&memmax); //set maximum virtual memory space to 2GB. 
Другие вопросы по тегам