предотвратить зависание системы / не отвечает из-за перестановки использования памяти


48

Если процесс требует много памяти, система перемещает все остальные процессы в файл подкачки. В том числе вроде бы необходимые процессы вроде сервера X11 или терминала.

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

Как этого можно избежать?

1) Отключить своп => Я часто запускаю множество процессов, которые затем становятся неактивными. Неактивные должны быть перемещены в своп.

2) Получить SSD => слишком дорого

3) установить максимальный объем памяти ulimit =>, но в случае сбоя программы требуется большой объем памяти. проблема не в том, что он использует слишком много, а в том, что он подавляет другие процессы

4) хранить важные программы (X11, bash, kill, top, ...) в памяти и никогда не менять их => это можно сделать? как? возможно только обменять большие программы?

5)


И это случилось снова :( Запустил gcc, когда Firefox был запущен, все было заблокировано на полчаса. Никаких движений мыши и чтения электронных книг
BeniBela

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

Похоже, что вам действительно нужно больше оперативной памяти. Или менее «неактивные» фоновые задачи.
Даниэль Б

2
Вы можете использовать комбинацию клавиш Alt + SysRq + F, чтобы запустить OOM-killer. Это может сократить лишнее время, необходимое для того, чтобы ваша система открыла консоль, чтобы вы могли завершить процесс.
Hololeap

Поправьте меня, если я ошибаюсь, но на самом деле эта проблема звучит так, будто система ищет место подкачки диска, которое должно существовать, но не существует (раздел подкачки слишком мал). Недостаточно места подкачки приведет к тому, что система «перегрузит» жесткий диск (или ssd) в поисках свободного места.
mchid

Ответы:


45

TL; DR

Краткий временный ответ

  • Самый простой : иметь меньший раздел подкачки и избегать попыток ядра оправдать ложь о том, что нет ограничений памяти при запуске процессов из медленного хранилища.
    • С большой заменой OOM (из менеджера памяти) не предпринимает действий достаточно скоро. Как правило, он учитывается в соответствии с виртуальной памятью и, по моему прошлому опыту, не убивал вещи до тех пор, пока не был заполнен весь своп, отсюда и система обхода и сканирования
  • Нужен большой своп на спящий режим?
    • Попытка / проблема : Установите некоторые ограничения (например, проверьте ulimit -v, и, возможно, установите жесткий или мягкий предел, используя asопцию в limits.conf). Раньше это работало достаточно хорошо, но благодаря внедрению WebKit gigacageмногие приложения gnome теперь ожидают неограниченного адресного пространства и не запускаются!
    • Покушение / проблематично : overcommit политика и отношение еще один способ , чтобы попытаться управлять и уменьшить это (например sysctl vm.overcommit_memory, sysctl vm.overcommit_ratio, но этот подход не работает для меня.
    • Сложно / сложно : Попробуйте применить приоритет cgroup к наиболее важным процессам (например, ssh), но в настоящее время это кажется громоздким для cgroup v1 (надеюсь, v2 облегчит это) ...

Я также нашел:

Долгосрочное решение

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

Некоторые интересные пятна:

Так что виноват не только плохой код пользовательского пространства и конфигурация / настройки по умолчанию для дистрибутива - ядро ​​справится с этим лучше

Комментарии к уже рассмотренным вариантам

1) Отключить своп

Рекомендуется предусмотреть хотя бы небольшой раздел подкачки ( нужен ли нам подкачка в современных системах? ). Отключение подкачки не только предотвращает выгрузку неиспользуемых страниц, но также может повлиять на стратегию эвристического превышения по умолчанию в ядре для выделения памяти ( что означает эвристика в Overcommit_memory = 0? ), Поскольку эта эвристика рассчитывает на страницы подкачки. Без свопа overcommit все еще может работать в эвристическом (0) или всегда (1) режимах, но сочетание стратегии no swap и never (2) overcommit, вероятно, является ужасной идеей. Так что в большинстве случаев никакой своп, скорее всего, не повлияет на производительность.

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

3) установить максимальный объем памяти ulimit

Это применимо только для каждого процесса, и, вероятно, разумно предположить, что процесс не должен запрашивать больше памяти, чем у системы физически! Так что, вероятно, полезно, чтобы одинокий сумасшедший процесс не вызывал побои, пока все еще был щедро настроен.

4) хранить важные программы (X11, bash, kill, top, ...) в памяти и никогда не менять их

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

выпуск 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:

       rss
          maximum resident set size (KB) (Ignored in Linux 2.4.30 and
          higher)

Так что установка ulimit для применения только к физическому использованию ОЗУ больше не выглядит пригодной для использования. следовательно

      as
          address space limit (KB)

кажется, единственная уважаемая перестраиваемая.

К сожалению, как подробно описано на примере WebKit / Gnome, некоторые приложения не могут работать, если выделено виртуальное адресное пространство.

cgroups должны помочь в будущем?

В настоящее время это кажется громоздким, но возможно включить некоторые флаги cgroup ядра cgroup_enable=memory swapaccount=1(например, в конфигурации grub), а затем попытаться использовать контроллер памяти cgroup, чтобы ограничить использование памяти.

У cgroups есть более продвинутые возможности ограничения памяти, чем у параметров ulimit. Примечания CGroup v2 намекают на попытки улучшить работу ulimits.

Объединенный учет памяти и обмена подкачки и ограничение заменены реальным контролем над пространством подкачки.

Параметры CGroup можно установить с помощью параметров управления ресурсами systemd . Например:

  • MemoryHigh
  • MemoryMax

Другие полезные опции могут быть

  • IOWeight
  • CPUShares

У них есть некоторые недостатки:

  1. Накладные расходы. В текущей документации докера кратко упоминается 1% дополнительного использования памяти и 10% снижения производительности (вероятно, в отношении операций выделения памяти - на самом деле это не указано).
  2. Cgroup / systemd в последнее время сильно переработан, поэтому поток вверх по течению подразумевает, что поставщики дистрибутивов Linux могут ждать, пока он установится первым.

В CGroup v2 они предлагают, memory.highчтобы это был хороший вариант для регулирования и управления использованием памяти группой процессов. Однако эта цитата предполагает, что для мониторинга ситуаций с нехваткой памяти требовалось больше работы (по состоянию на 2015 год).

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

Учитывая, что инструменты пространства пользователя systemd и cgroup являются сложными, я не нашел простого способа установить что-то подходящее и использовать это в дальнейшем. Документация cgroup и systemd для Ubuntu невелика. Дальнейшая работа должна быть для дистрибутивов с настольными выпусками, чтобы использовать cgroups и systemd, чтобы под высоким давлением памяти компоненты ssh и X-Server / оконный менеджер получали более высокий приоритет доступа к ЦП, физической ОЗУ и IO хранилища, чтобы избежать конкуренции с процессами заняты обменом. Функции ядра и приоритета ввода / вывода уже давно существуют. Похоже, приоритетного доступа к физической ОЗУ не хватает.

Однако даже приоритеты процессора и ввода-вывода не установлены должным образом !? Когда я проверял ограничения systemd cgroup, общие ресурсы центрального процессора и т. Д., Насколько я могу судить, Ubuntu не пекла ни в каких заранее определенных приоритетах. Например, я побежал:

systemctl show dev-mapper-Ubuntu\x2dswap.swap

Я сравнил это с одним и тем же выводом для 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

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

В моем случае коэффициент фиксации по умолчанию был:

$ sysctl vm.overcommit_ratio
vm.overcommit_ratio = 50

Но это вступает в силу в полной мере только при изменении политики, чтобы отключить чрезмерную загрузку и применить соотношение

sudo sysctl -w vm.overcommit_memory=2

Отношение подразумевало, что всего 24 ГБ памяти может быть выделено в целом (16 ГБ ОЗУ * 0,5 + 16 ГБ SWAP). Таким образом, я, вероятно, никогда не увижу, что OOM будет отображаться, и, скорее всего, у процессов будет меньше доступа к памяти в процессе подкачки. Но я также, вероятно, пожертвую общей эффективностью системы.

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

Как VM overcommit память работает, есть больше информации.

Для этого я решил вернуться к значению по умолчанию, sudo sysctl -w vm.overcommit_memory=0учитывая, что графический стек всего настольного компьютера и приложения в нем все равно аварийно завершают работу.


4
Это лучшая рецензия, которую я видел по этому вопросу, и вы не прибегаете к «просто покупайте больше оперативной памяти!» Одна вещь, которую вы не упоминаете, это то, как параметры конфигурации ядра играют в этом. Например, будет ли используемая модель preemtion или планировщик ввода / вывода иметь какое-либо существенное влияние на что-либо из этого?
Hololeap

2
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. Есть ли доказательства этому? Я полагаю, что ядро ​​прекрасно работает без настроенного свопа
ygrek

@ygrek, спасибо, что формулировка выглядит немного неправильно - overcommit по-прежнему работает без подкачки, если не выбран режим never overcommit (2). Эвристический режим overcommit по умолчанию (0) или режим всегда commit (1), вероятно, по-прежнему работают без подкачки. Не могу вспомнить, где я читал, что отключение подкачки вредит способности кода overcommit распределять память (и какой режим это затрагивало определенно). Погуглил снова без удачи, но это был полу-полезный пост: stackoverflow.com/questions/38688824/… Я отредактирую ответ соответствующим образом.
JPvRiel

Я надеялся, что патч фоновой обратной записи поможет мне, но я нахожусь на очень новом ядре (4.14.81) и сталкиваюсь со значительными проблемами отзывчивости при интенсивном вводе-выводе диска (независимо от того, была ли своп причиной или нет). Интересно, не вызывает ли какой-либо проблемы с производительностью менеджер устройств или мое шифрование LUKS? Я действительно мало знаю, как отладить такого рода проблемы.
Дариус Джахандари
Используя наш сайт, вы подтверждаете, что прочитали и поняли нашу Политику в отношении файлов cookie и Политику конфиденциальности.
Licensed under cc by-sa 3.0 with attribution required.