27.01.2020 14:20
OlegON
 
В убогой недоос все просто, есть память, есть своп. Когда это все кончается, система начинает сбоить, программки падать с непонятными ошибками и т.п.

В Linux все гораздо интереснее.



В параметрах ядра (указываются в /etc/sysctl.conf и просматриваются через sysctl -a) есть параметры
Код:
vm.overcommit_memory = 0
vm.overcommit_ratio = 50
обратимся к документации
Цитата:
overcommit_memory
Определяет условия разрешения и отказа запросов больших объемов памяти. Возможные значения:
0 (по умолчанию) — ядро использует эвристический алгоритм для расчета перерасхода памяти, принимая во внимание объем доступной памяти и число неверных запросов. Но поскольку выделение памяти осуществляется на основе эвристического, а не точного алгоритма, это может привести к превышению допустимой нагрузки на память.
1 — ядро не обрабатывает перерасход памяти. При этом вероятность превышения нагрузки на память возрастает, но в то же время увеличивается производительность задач, активно использующих память.
2 — отказ обработки запросов, запрашивающих память, размер которой превышает суммарный размер памяти пространства подкачки и ОЗУ в соответствии с overcommit_ratio.
Примечание
Этот параметр должен использоваться в только в тех системах, где размер пространства подкачки превышает общий размер физической памяти.
любители хардкора, могут выставить параметры, чтобы поведение системы было ближе к виндовому
Код:
vm.overcommit_memory = 2
vm.overcommit_ratio = 100
это обозначает, что программы, которые будут запрашивать памяти больше, чем 100% от свопа+ОЗУ, будут падать по нехватке памяти. Самое забавное, что в большинстве программ это исключение обрабатывается так себе, кривовато, поэтому такие параметры я ставить не рекомендую. Иначе будет все неожиданно падать еще даже до того момента, как память и своп реально закончатся.

Если все оставить по умолчанию (как в первой цитате), то поведение системы будет следующим: память будет заполняться, потом часть вываливаться в своп и, наконец, когда закончится и память, и своп, придет страшный OOM killer (Out Of Memory). Он, от бедра, перестреляет всех жрунов памяти. Поверьте, по логичности работы системы это куда вменяемее, чем падающие софтинки в виндовом варианте. Какие-то софтинки можно защитить от киллера, для этого есть параметр, который может быть задан для отдельных процессов, обеспечивая тем самым тонкий контроль над тем, какие процессы oom_killer будет останавливать. Он размещается в /proc/PID/ (PID — идентификатор процесса).
Цитата:
oom_adj
Значение в диапазоне от -16 до 15 определяет oom_score процесса. Чем больше oom_score, тем больше вероятность того, что oom_killer остановит процесс. Значение -17 отключает oom_killer для процесса.
я предпочитаю -17 использовать очень редко и только для чего-то гарантированно нетекущего и очень хрупкого. Получить неработоспособную систему куда хуже, чем убийство неработоспособного кривоподелия.

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

Для этого существуют две программки earlyoom и nohang. В отличие от штатного oom_killer, эти программки достаточно конфигурабельны. Их можно настроить так, чтобы подвисания были вообще незаметны, а убийство жручих софтинок происходило раньше, чем все встанет колом. Я у себя на ноутбуке использую nohang, а на "сервере" earlyoom, просто больше присматриваюсь к nohang, который еще может и уведомления выдавать на десктопе.
28.01.2020 17:05
OlegON
 
Немного тезисов из переписки

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

2. Трудно найти оптимальное значение overcommit ratio, хотя это может быть не проблема не сервере с предсказуемой нагрузкой. - Если выставить большой ratio, то получим тот же эффект, что и при наличии дефолтного оверкоммита, и будет приходить киллер. При низком overcommit ratio просто получим неполную утилизацию физической памяти. - Процессы будуть падать при полупустом свопе или при полупустой памяти. - Если нужно огараничить память, то лучше использовать контрольные группы и MemoryMax и MemorySwapMax - эти параметры ограничивают физическую память, а не виртуальную, в отличие от случая с запретом оверкоммита. Еще альтератива - юзерспейсный демон earlyoom - он сначала отправляет SIGTERM, завершая процессы по возможности более корректно

1. Я знаю один способ отключения киллера - panic on oom. Разве есть другие? 2. оом киллер надо не отключать, а вызывать по возможности раньше. Не вызванный киллер - умершая система. Киллер - это лекарство от смерти. "если уж хочется жить без oom" - то я предпочитаю earlyoom - процессы завершаются по SIGTERM, до дедлоков с зависаниями не доходит дело.

Ограничение оверкоммита не всегда означает отключение киллера - многое еще зависит от overcommit ratio

Еще момент: киллер убивает процесс с наибольшим oom_score - обычно самый жирный. С ограничением оверкоммита упадет не обязатено самый жирный - могут падать и мелкие процессы, если жирный процесс протекает, но при этом обрабатывает ошибки выделения.
08.02.2020 19:44
OlegON
 
Еще интересная штука - oomd, но она больше для серверов и выносит приложения группами. Поджирает проц и обязательно требует своп.

Форум на базе vBulletin®
Copyright © Jelsoft Enterprises Ltd.
В случае заимствования информации гипертекстовая индексируемая ссылка на Форум обязательна.