LINUX.ORG.RU

Выпуск earlyoom 1.3, процесса для раннего реагирования на нехватку памяти

 , ,


1

2

После семи месяцев разработки опубликован выпуск фонового процесса earlyoom 1.3, который периодически проверяет объем доступной памяти (MemAvailable, SwapFree) и пытается на ранней стадии отреагировать на возникновения нехватки памяти.

Если объём доступной памяти меньше заданного значения, то earlyoom принудительно (через отправку SIGTERM или SIGKILL) завершит работу процесса, наиболее активно потребляющего память (имеющего самое большое значение /proc/*/oom_score), не доводя состояние системы до очистки системных буферов и мешающего работе своппинга (обработчик OOM (Out Of Memory) в ядре срабатывает когда состояние нехватки памяти уже достигло критичных значений и обычно к этому моменту система уже не реагирует на действия пользователя).

Earlyoom поддерживает отправку уведомлений о принудительно завершённых процессах на рабочий стол (с помощью notify-send), а также предоставляет возможность определения правил, в которых при помощи регулярных выражений можно задать имена процессов, завершение которых предпочтительно (опция "--prefer") или остановки которых стоит избегать (опция "--avoid").

Основные изменения в новом выпуске:

  • Реализовано ожидание завершения процесса после отправки ему сигнала. Это устраняет проблему, заключающуюся в том, что earlyoom иногда убивает более одного процесса, когда одного будет достаточно;
  • Добавлен вспомогательный скрипт (notify_all_users.py) для уведомления всех залогиненых пользователей о завершении процессов через уведомления notify-send;
  • Исправлено некорректное отображение некоторых имен процессов, содержащих UTF-8 символы;
  • Принят кодекс поведения (Contributor Covenant Code of Conduct).

>>> Подробности

Реализовано ожидание завершения процесса после отправки ему сигнала. Это устраняет проблему

Теперь earlyoom стал production ready. Не хватает только более подробной документации. Ах да, не хватает еще информации о состоянии процессов, о состоянии убиваемого процесса перед корректирующим действием. Аутпут слишком короткий.

Earlyoom лёгок и стабилен.

VmRSS меньше мегабайта, нагрузка на процессок близка к нулю.

Напоминаю, что предотвращение OOM в юзерспейсе - это хорошая практика.

hakavlad ()

В теории, что мешает сохранить состояние процесса на диск, а потом, если он снова понадобится, выгрузить его обратно? Почему так не делают в современных ОС?

Landgraf ★★★★ ()
Ответ на: комментарий от Landgraf

А если процесс ожидает, какой-то ресурс, а он умер, пока процесс лежал на диске. Что тогда делать? Или, зеркальная ситуация, процесс держал ресурс и лёг на диск. А кто ресурс отдавать будет, если он нужен кому-то.

Ресурс имеется ввиду не память (фиг бы с ней), а дескрипторы, сокеты и т.д., короче совместно используемые ресурсы. Гипотетически это можно, наверное, разрулить, но точно не в формате лёгкого юзерспейсного демона.

SkyMaverick ()
Ответ на: комментарий от mittorn

когда линукс начинает сбрасывать буферы чтобы освободить память, он начинает потреблять больше памяти и зависает навсегда. можно открыть oom.c в ядре (или oomkill.c, не помню) и почитать, что там написано, что-то типа «этот файл является обучающим для людей которые хотят попробовать попрограммировать ядро».

поэтому оомкилл в линуксе уже лет десять как не работает, его всё время ломают и ломают. а единственный способ как заставить линукс работать - программа в юзерспейсе которая срабатывает до оом, т.е. до того как стало слишком поздно.

такие дела.

anonymous ()
Ответ на: комментарий от mittorn

Перед ООМом почти всегда бывает жуткий свопинг, создающий нехилую нагрузку на диск. Если ты в этот момент будешь сбрасывать кэши, система вообще встанет раком.

Не говоря уж о том, что чем раньше будет свободная память, тем лучше, а кэш может сбрасываться долго.

slvrn ★★★ ()
Ответ на: комментарий от slvrn

анон вменяем. линукс уже лет десять виснет если работает без свопа и заканчивается память. если вы с этим не сталкивались, то либо у вас своп включён, либо память не заканчивалась по хардкору. оомкилл давно поломан, своп тут ни при чём, ядро «виснет» именно тогда когда начинает сбрасывать буферы. ну т.е. оно не совсем виснет, если вы подождёте 48 часов, то может отпустит, но вообще, если надо работать, то помогает только аппаратный ресет.

anonymous ()
Ответ на: комментарий от Landgraf

В теории, что мешает сохранить состояние процесса на диск, а потом, если он снова понадобится, выгрузить его обратно? Почему так не делают в современных ОС?

Делают. Это как раз своп и виртуальная память)

goingUp ★★★★★ ()
Ответ на: комментарий от anonymous

Так это другая проблема. Свободной памяти слишком мало, чтобы оставлять кэши, но она еще есть, поэтому ООМ не приходит. Вот закончится она, и какой-нибудь жирный процесс умрет.

А своп нужен, с этим я согласен.

slvrn ★★★ ()

Earlyoom поддерживает отправку уведомлений о принудительно завершённых процессах на рабочий стол (с помощью notify-send)

Разве? На гитхабе висит #54 с 2018-03-12.

Odalist ★★★★★ ()
Последнее исправление: Odalist (всего исправлений: 1)
Ответ на: комментарий от sergej

голос разума.

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

Iron_Bug ★★★★ ()
Ответ на: комментарий от anonymous

Он «виснет» когда CPU все время тратит только на выполнение процессов ядра (пункт sy в топе). При этом вся юзерспейсщина тормозит и не откликается. Это происходит, когда нет свободной памяти и нет свопа. Примерно в это же время приходит ООМ.

Поэтому неправильно говорить, что линукс виснет из-за ООМа. Он виснет из-за отсутствия свопа.

slvrn ★★★ ()
Ответ на: комментарий от Iron_Bug

Не все системы являются встроенными. Не во всех набор софта и нагрузки предопределены.

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

Пример 2. Мелкий сервер с сайтиком случайно подвергся хабраэффекту. -> память кончается -> OOM

Юзерспейсный обработчик - это просто еще один способ спать спокойне, он не противоречит идее писать хороший софт или выставлять лимиты. Он просто позволяет обрабатывать нехватку памяти более своевременно, более гибко, более качественно по сравнению с дефолтным обработчиком.

hakavlad ()
Ответ на: комментарий от Iron_Bug

Так в эмбеде и соперничающих программ как правило нет, либо они заранее известны, и, как слышал, динамическое выделение там не приветствуется в принципе и память выделяется один раз и на всю жизнь. Хочется аттракцион уровня «перекомпилируй, чтобы работать с N+ файлами/записями/окнами/кадрами/элементами/процессами»?

WDWTFWW ()
Последнее исправление: WDWTFWW (всего исправлений: 1)
Ответ на: комментарий от slvrn

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

своп во-первых не нужен, во-вторых в большинстве виртуалок свопа не будет - нет смысла, проще ресетнуть виртуалку. чинить оомкилл тоже нет смысла, его постоянно как-то переделывают и снова ломают.

последний раз оомкилл работал как оомкилл где-то 2000-х. это известная проблема, но всем всё равно, погугли.

anonymous ()
Ответ на: комментарий от anonymous

последний раз оомкилл работал как оомкилл где-то 2000-х.

У меня только что сработал:

июн 05 22:18:39 PC kernel: [30322] 1000 30322 194620 11803 223 3 0 0 kate июн 05 22:18:39 PC kernel: [30329] 1000 30329 5363 1302 13 3 0 0 bash июн 05 22:18:39 PC kernel: [30468] 1000 30468 194624 11737 228 3 0 0 kate июн 05 22:18:39 PC kernel: [31811] 1000 31811 88431 5575 94 3 0 0 leafpad июн 05 22:18:39 PC kernel: [19572] 1000 19572 908025 269046 1090 6 0 0 firefox-esr июн 05 22:18:39 PC kernel: [20205] 1000 20205 735896 154762 700 6 0 0 Web Content июн 05 22:18:39 PC kernel: [20321] 1000 20321 197054 8865 174 3 0 0 pavucontrol июн 05 22:18:39 PC kernel: [20846] 1000 20846 477124 43471 249 5 0 0 Telegram июн 05 22:18:39 PC kernel: [21493] 1000 21493 49822 3482 82 4 0 0 file.so июн 05 22:18:39 PC kernel: [21803] 1000 21803 76612 4778 85 4 0 0 lxterminal июн 05 22:18:39 PC kernel: [21806] 1000 21806 3669 419 12 3 0 0 gnome-pty-helpe июн 05 22:18:39 PC kernel: [21807] 1000 21807 5360 1253 14 3 0 0 bash июн 05 22:18:39 PC kernel: [21816] 1000 21816 2395632 2394531 4684 13 0 0 tail июн 05 22:18:39 PC kernel: Out of memory: Kill process 21816 (tail) score 676 or sacrifice child июн 05 22:18:39 PC kernel: Killed process 21816 (tail) total-vm:9582528kB, anon-rss:9576600kB, file-rss:1524kB, shmem-rss:0kB июн 05 22:18:53 PC sudo[21818]: user : TTY=pts/0 ; PWD=/home/user ; USER=root ; COMMAND=/bin/journalctl -e июн 05 22:18:53 PC sudo[21818]: pam_unix(sudo:session): session opened for user root by (uid=0)

hakavlad ()
Ответ на: комментарий от anonymous

оомкилл так написан, что сначала он попытается сбросить буферы

Он не сбрасывает буферы, этим занимается ядро. Он только убивает.

чинить оомкилл тоже нет смысла, его постоянно как-то переделывают и снова ломают.

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

slvrn ★★★ ()
Ответ на: комментарий от sergej

лимиты

А что такое лимиты? Там столько нюансов, что так просто не получится это легко описать, и зареализовать.

А вообще занятно, совсем до недавнего времени использовал macOS на 4 ГБ ОЗУ, и оно там вылезало так прилично без проблем, как представлю, чтобы я с линуксом делал - бррр... В линукс только кучу ОЗУ пихать.

fornlr ★★★★★ ()
Ответ на: комментарий от slvrn

Про no regressions rule тебе напомнить?

И чего это? Я вот не знаю. Но все равно не могу представить такую магию, которая будет делать регрессионные тесты для каких-то маловажных случаев.

fornlr ★★★★★ ()
Ответ на: комментарий от fornlr

Если регрессия всплыла, то откатывается коммит в ядро, который эту регрессию и сделал. Или чинится так, чтобы все работало как раньше. Поэтому глупо говорить, что ООМ сломали и не чинят.

slvrn ★★★ ()
Ответ на: комментарий от hakavlad

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

2. юзеру десктопа никто не мешает управлять памятью, если он этого хочет. чай, не маздай :) ну а если юзер совсем уж хомяк, то пусть докупает оперативу. впрочем, у меня на десктопе ни разу такая ситуация не возникала, за все хрен знает сколько лет работы. так что десктоп перегрузить - это ещё постараться надо.

я не против этого обработчика. просто это способ залатывания дыр в софте.

Iron_Bug ★★★★ ()
Ответ на: комментарий от slvrn

тебя на kernel.org забанили?

/**
 * out_of_memory - kill the "best" process when we run out of memory
 * @oc: pointer to struct oom_control
 *
 * If we run out of memory, we have the choice between either
 * killing a random task (bad), letting the system crash (worse)
 * OR try to be smart about which process to kill. Note that we
 * don't have to be perfect here, we just have to be good.
 */
bool out_of_memory(struct oom_control *oc)
{
	unsigned long freed = 0;
	enum oom_constraint constraint = CONSTRAINT_NONE;

	if (oom_killer_disabled)
		return false;

	if (!is_memcg_oom(oc)) {
		blocking_notifier_call_chain(&oom_notify_list, 0, &freed);
		if (freed > 0)
			/* Got some memory back in the last second. */
			return true;
	}

вызов оомкиллера может вообще не прибить ни одного процесса.

/*
 *  linux/mm/oom_kill.c
 * 
 *  Copyright (C)  1998,2000  Rik van Riel
 *	Thanks go out to Claus Fischer for some serious inspiration and
 *	for goading me into coding this file...
 *  Copyright (C)  2010  Google, Inc.
 *	Rewritten by David Rientjes
 *
 *  The routines in this file are used to kill a process when
 *  we're seriously out of memory. This gets called from __alloc_pages()
 *  in mm/page_alloc.c when we really run out of memory.
 *
 *  Since we won't call these routines often (on a well-configured
 *  machine) this file will double as a 'coding guide' and a signpost
 *  for newbie kernel hackers. It features several pointers to major
 *  kernel subsystems and hints as to where to find out what things do.
 */

оомкилл стабильно меняется 2-7 раз в месяц.

anonymous ()
Ответ на: комментарий от anonymous

вызов оомкиллера может вообще не прибить ни одного процесса.

Если ООМ отключен или если внезапно нашлась память? Это да, но в первом случае - ССЗБ, а во втором - он уже не нужен.

оомкилл стабильно меняется 2-7 раз в месяц.

Это не повод называть его нерабочим.

slvrn ★★★ ()
Ответ на: комментарий от sergej

Если ситуация чуть сложнее, то система действительно становится раком.

Ну тогда это уже не проблема ООМа. Такие ситуации надо решать добавлением памяти.

slvrn ★★★ ()
Ответ на: комментарий от slvrn

ну вот ты сам ответил на все свои вопросы. и оомкилл работает, и багов нет, всё хорошо, ничего не поломано и ничего чинить не надо. зачем только ты свои тупые вопросы задвал я не могу понять.

anonymous ()
Ответ на: комментарий от slvrn

Если регрессия всплыла, то откатывается коммит в ядро, который эту регрессию и сделал. Или чинится так, чтобы все работало как раньше. Поэтому глупо говорить, что ООМ сломали и не чинят.

Ну нет кончено. Есть приоритеты.

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

Так же во многом и с OOM - не приоритет. И у него нет как у многих других сложных вещей всего два состояния (отлично/плохо).

fornlr ★★★★★ ()
Последнее исправление: fornlr (всего исправлений: 1)
Ответ на: комментарий от fornlr

Есть приоритеты.

Какие приоритеты? Если что-то поломалось - коммит откатывают. Или делают так, чтобы и приоритеты работали, и все старое не ломалось.

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

Давай ссылку.

Так же во многом и с OOM - не приоритет.

Это очень важная вещь, вообще-то. Или ты линукс только на десктопах видел?

slvrn ★★★ ()