Если процесс требует много памяти, система перемещает все остальные процессы в файл подкачки. В том числе вроде бы необходимые процессы вроде сервера X11 или терминала.
Таким образом, если процесс продолжает выделяться без ограничений, все перестает отвечать, пока этот процесс не будет убит OOM-киллером. Мой ноутбук кажется особенно чувствительным и реагирует крайне плохо. Я просто потратил ВЕСЬ ЧАС, ожидая завершения процесса, во время которого даже курсор мыши не мог быть перемещен.
Как этого можно избежать?
1) Отключить своп => Я часто запускаю множество процессов, которые затем становятся неактивными. Неактивные должны быть перемещены в своп.
2) Получить SSD => слишком дорого
3) установить максимальный объем памяти ulimit =>, но в случае сбоя программы требуется большой объем памяти. проблема не в том, что он использует слишком много, а в том, что он подавляет другие процессы
4) хранить важные программы (X11, bash, kill, top, ...) в памяти и никогда не менять их => это можно сделать? как? возможно только обменять большие программы?
5)
Ответы:
TL; DR
Краткий временный ответ
ulimit -v
, и, возможно, установите жесткий или мягкий предел, используяas
опцию вlimits.conf
). Раньше это работало достаточно хорошо, но благодаря внедрению WebKitgigacage
многие приложения gnome теперь ожидают неограниченного адресного пространства и не запускаются!sysctl vm.overcommit_memory
,sysctl vm.overcommit_ratio
, но этот подход не работает для меня.Я также нашел:
Долгосрочное решение
подождите и надейтесь, что некоторые апстрим-патчи попадут в стабильные ядра дистрибутива. Также надеемся, что производители дистрибутивов лучше настроят параметры ядра по умолчанию и лучше используют системные группы cd для определения приоритетов отзывчивости графического интерфейса в настольных версиях.
Некоторые интересные пятна:
Так что виноват не только плохой код пользовательского пространства и конфигурация / настройки по умолчанию для дистрибутива - ядро справится с этим лучше
Комментарии к уже рассмотренным вариантам
Рекомендуется предусмотреть хотя бы небольшой раздел подкачки ( нужен ли нам подкачка в современных системах? ). Отключение подкачки не только предотвращает выгрузку неиспользуемых страниц, но также может повлиять на стратегию эвристического превышения по умолчанию в ядре для выделения памяти ( что означает эвристика в Overcommit_memory = 0? ), Поскольку эта эвристика рассчитывает на страницы подкачки. Без свопа overcommit все еще может работать в эвристическом (0) или всегда (1) режимах, но сочетание стратегии no swap и never (2) overcommit, вероятно, является ужасной идеей. Так что в большинстве случаев никакой своп, скорее всего, не повлияет на производительность.
Например, подумайте о длительном процессе, который первоначально затрагивает память для однократной работы, но затем не может освободить эту память и продолжает работать в фоновом режиме. Ядро должно будет использовать RAM для этого, пока процесс не закончится. Без какого-либо обмена ядро не может выгнать его из-за чего-то, что действительно хочет активно использовать оперативную память. Также подумайте о том, сколько разработчиков ленивы и явно не освобождают память после использования.
Это применимо только для каждого процесса, и, вероятно, разумно предположить, что процесс не должен запрашивать больше памяти, чем у системы физически! Так что, вероятно, полезно, чтобы одинокий сумасшедший процесс не вызывал побои, пока все еще был щедро настроен.
Хорошая идея, но тогда эти программы заберут память, которую они активно не используют. Это может быть приемлемо, если программа запрашивает только скромный объем памяти.
выпуск systemd 232 только что добавлены некоторые опции, которые делают это возможным: я думаю, что можно использовать MemorySwapMax = 0, чтобы предотвратить отключение какой-либо части памяти (службы) типа ssh.
Тем не менее, возможность приоритезировать доступ к памяти была бы лучше.
Длинное объяснение
Ядро linux более приспособлено для серверных рабочих нагрузок, поэтому отзывчивость GUI, к сожалению, была второстепенной задачей ... Настройки управления памятью ядра в настольной версии Ubuntu 16.04 LTS, похоже, не отличались от других серверных выпусков. Он даже соответствует значениям по умолчанию в RHEL / CentOS 7.2, обычно используемом в качестве сервера.
OOM, ulimit и обмен целостности на отзывчивость
Перестановка перестановки (когда рабочий набор памяти, т. Е. Страницы, считываемые и записываемые в заданный короткий промежуток времени, превышают физическую ОЗУ), всегда блокирует ввод-вывод хранилища - никакое ядро ядра не может спасти систему от этого, не убивая процесс или два ...
Я надеюсь, что настройки Linux OOM, появившиеся в более новых ядрах, распознают, что этот рабочий набор превышает физическую память и убивает процесс. Когда этого не происходит, возникает проблема с молотом. Проблема в том, что с большим разделом подкачки это может выглядеть так, как будто система все еще имеет запас мощности, в то время как ядро весело выполняет коммиты и по-прежнему обслуживает запросы памяти, но рабочий набор может перетекать в раздел подкачки, эффективно пытаясь обработать хранилище так, как если бы это оперативная память
На серверах он допускает снижение производительности из-за обдумывания, медленного, без потери данных, компромисса. На настольных компьютерах компромисс отличается, и пользователи предпочли бы небольшую потерю данных (жертвоприношение процессов), чтобы держать вещи отзывчивыми.
Это была хорошая смешная аналогия с ООМ: oom_pardon, иначе не убивай мой xlock
Между прочим,
OOMScoreAdjust
это еще одна системная опция, помогающая взвешивать и избегать процессов уничтожения OOM, считающихся более важными.буферизованная обратная запись
Я думаю " Сделать фоновую обратную запись не отстой » поможет избежать некоторых проблем, когда процесс, из-за которого ОЗУ процесса вызывает другой обмен (запись на диск) и массовая запись на диск, останавливает все остальное, требующее ввода-вывода. Это не является причиной проблемы само по себе, но это добавляет к общей деградации реагирования.
ограничение ограничений
Одна из проблем с ulimits заключается в том, что ограничение учета применяется к адресному пространству виртуальной памяти (что подразумевает объединение как физического, так и пространства подкачки). Согласно
man limits.conf
:Так что установка ulimit для применения только к физическому использованию ОЗУ больше не выглядит пригодной для использования. следовательно
кажется, единственная уважаемая перестраиваемая.
К сожалению, как подробно описано на примере WebKit / Gnome, некоторые приложения не могут работать, если выделено виртуальное адресное пространство.
cgroups должны помочь в будущем?
В настоящее время это кажется громоздким, но возможно включить некоторые флаги cgroup ядра
cgroup_enable=memory swapaccount=1
(например, в конфигурации grub), а затем попытаться использовать контроллер памяти cgroup, чтобы ограничить использование памяти.У cgroups есть более продвинутые возможности ограничения памяти, чем у параметров ulimit. Примечания CGroup v2 намекают на попытки улучшить работу ulimits.
Параметры CGroup можно установить с помощью параметров управления ресурсами systemd . Например:
Другие полезные опции могут быть
У них есть некоторые недостатки:
В CGroup v2 они предлагают,
memory.high
чтобы это был хороший вариант для регулирования и управления использованием памяти группой процессов. Однако эта цитата предполагает, что для мониторинга ситуаций с нехваткой памяти требовалось больше работы (по состоянию на 2015 год).Учитывая, что инструменты пространства пользователя systemd и cgroup являются сложными, я не нашел простого способа установить что-то подходящее и использовать это в дальнейшем. Документация cgroup и systemd для Ubuntu невелика. Дальнейшая работа должна быть для дистрибутивов с настольными выпусками, чтобы использовать cgroups и systemd, чтобы под высоким давлением памяти компоненты ssh и X-Server / оконный менеджер получали более высокий приоритет доступа к ЦП, физической ОЗУ и IO хранилища, чтобы избежать конкуренции с процессами заняты обменом. Функции ядра и приоритета ввода / вывода уже давно существуют. Похоже, приоритетного доступа к физической ОЗУ не хватает.
Однако даже приоритеты процессора и ввода-вывода не установлены должным образом !? Когда я проверял ограничения systemd cgroup, общие ресурсы центрального процессора и т. Д., Насколько я могу судить, Ubuntu не пекла ни в каких заранее определенных приоритетах. Например, я побежал:
Я сравнил это с одним и тем же выводом для ssh, samba, gdm и nginx. Важные вещи, такие как графический интерфейс и консоль удаленного администратора, должны одинаково бороться со всеми другими процессами, когда происходит перегрузка.
Пример ограничений памяти у меня на 16 ГБ ОЗУ
Я хотел включить hibernate, поэтому мне нужен был большой раздел подкачки. Следовательно, попытка смягчить с помощью ulimits и т. Д.
ULIMIT
Я ставлю
* hard as 16777216
в/etc/security/limits.d/mem.conf
такие , что ни один процесс не будет разрешено требовать больше памяти , чем физически возможно. Я не буду препятствовать уничтожению всего вместе, но без этого, только один процесс с жадным использованием памяти или утечка памяти, может вызвать поражение. Например, я видел, какgnome-contacts
высасывал 8 ГБ + памяти при выполнении таких рутинных задач, как обновление глобального списка адресов с сервера обмена ...Как видно из
ulimit -S -v
примера, во многих дистрибутивах этот жесткий и мягкий лимит установлен как «неограниченный», в теории процесс может закончиться запросом большого количества памяти, но только активно используя подмножество, и работать счастливо, думая, что ему дали 24 ГБ ОЗУ, в то время как система имеет только 16 ГБ. Вышеуказанное жесткое ограничение приведет к тому, что процессы, которые могли бы нормально работать, будут прерваны, когда ядро отклонит их жадные спекулятивные запросы памяти.Тем не менее, он также ловит безумные вещи, такие как контакты gnome, и вместо того, чтобы терять отзывчивость моего рабочего стола, я получаю ошибку «недостаточно свободной памяти»:
Сложности настройки ulimit для адресного пространства (виртуальная память)
К сожалению, некоторые разработчики любят делать вид, что виртуальная память - это бесконечный ресурс, и установка ограничения на виртуальную память может сломать некоторые приложения. Например, в WebKit (от которого зависят некоторые приложения gnome) добавлена
gigacage
функция безопасности, которая пытается распределить безумные объемы виртуальной памяти, и происходятFATAL: Could not allocate gigacage memory
ошибки с нахальным намекомMake sure you have not set a virtual memory limit
. Обходной путь,GIGACAGE_ENABLED=no
отказывается от преимуществ безопасности, но также не позволяет ограничивать выделение виртуальной памяти, также отказывается от функции безопасности (например, контроль ресурсов, который может предотвратить отказ в обслуживании). По иронии судьбы, между разработчиками gigacage и gnome они, похоже, забывают, что ограничение выделения памяти само по себе является контролем безопасности. И, к сожалению, я заметил, что приложения gnome, основанные на gigacage, не удосуживаются явно запросить более высокий лимит, поэтому даже мягкий лимит нарушает ситуацию в этом случае.Справедливости ради следует отметить, что если бы ядро справлялось с задачей запретить выделение памяти на основе использования резидентной памяти вместо виртуальной памяти, то притворная неограниченная виртуальная память была бы менее опасной.
overcommit
Если вы предпочитаете, чтобы приложениям было отказано в доступе к памяти, и вы хотите прекратить чрезмерную загрузку, используйте приведенные ниже команды, чтобы проверить, как ваша система ведет себя при высоком давлении в памяти.
В моем случае коэффициент фиксации по умолчанию был:
Но это вступает в силу в полной мере только при изменении политики, чтобы отключить чрезмерную загрузку и применить соотношение
Отношение подразумевало, что всего 24 ГБ памяти может быть выделено в целом (16 ГБ ОЗУ * 0,5 + 16 ГБ SWAP). Таким образом, я, вероятно, никогда не увижу, что OOM будет отображаться, и, скорее всего, у процессов будет меньше доступа к памяти в процессе подкачки. Но я также, вероятно, пожертвую общей эффективностью системы.
Это приведет к сбою многих приложений, поскольку разработчики обычно не корректно обрабатывают ОС, отклоняя запрос на выделение памяти. Он обменивает случайный риск затягивания блокировки из-за перебора (потеря всей вашей работы после полной перезагрузки) и более частого риска сбоя различных приложений. В моем тестировании это не сильно помогло, потому что рабочий стол сам по себе падал, когда система находилась под давлением памяти и не могла выделить память. Однако, по крайней мере, консоли и SSH все еще работали.
Как VM overcommit память работает, есть больше информации.
Для этого я решил вернуться к значению по умолчанию,
sudo sysctl -w vm.overcommit_memory=0
учитывая, что графический стек всего настольного компьютера и приложения в нем все равно аварийно завершают работу.источник
but the kernel won't be able to use an overcommit strategy for allocating memory and this will likely hurt performance. Even a smaller swap partition allows this.
Есть ли доказательства этому? Я полагаю, что ядро прекрасно работает без настроенного свопа