Убийца OOM в Linux время от времени наносит ущерб различным приложениям, и кажется, что на самом деле мало что сделано на стороне разработчиков ядра, чтобы улучшить это. Не лучше ли в качестве наилучшей практики при настройке нового сервера отменить настройку по умолчанию при чрезмерной загрузке памяти, то есть отключить ее ( vm.overcommit_memory=2
), если вы не уверены, что хотите включить ее для своего конкретного использования? И каковы будут те случаи использования, когда вы знаете, что хотите использовать чрезмерную загрузку?
В качестве бонуса, так как поведение в случае vm.overcommit_memory=2
зависит от vm.overcommit_ratio
пространства подкачки и пространства подкачки, что было бы хорошим эмпирическим правилом для определения размеров последних двух, чтобы вся эта установка продолжала работать разумно?
Убийца OOM наносит ущерб, только если вы перегрузили свою систему. Дайте ему достаточно свопа, и не запускайте приложения, которые вдруг решают съесть огромное количество оперативной памяти, и у вас не возникнет проблем.
Чтобы конкретно ответить на ваши вопросы:
brk
(2) (и обертками, которые его используют, такими какmalloc
(3)), возвращающими ошибку. Когда я экспериментировал с этим на моей предыдущей работе, было больше хлопот, чтобы получить все, что способно обрабатывать ошибки нехватки памяти, чем просто бороться с последствиями OOM (который, в нашем случае, было гораздо хуже, чем перезапускать случайный сервис, если произошла OOM - нам пришлось перезагрузить весь кластер, потому что GFS - это испаряющаяся куча фекалий).По сути, мой опыт показывает, что отключение overcommit - это хороший эксперимент, который редко работает так же хорошо на практике, как звучит в теории. Это прекрасно согласуется с моим опытом работы с другими переменными в ядре - разработчики ядра Linux почти всегда умнее вас, и настройки по умолчанию работают лучше всего в подавляющем большинстве случаев. Оставьте их в покое, и вместо этого найдите, в каком процессе произошла утечка, и устраните ее.
источник
Хм, я не полностью убежден аргументами в пользу сверхкоммитов и убийцы OOM ... Когда womble пишет,
«Убийца OOM наносит ущерб только в том случае, если вы перегружаете свою систему. Дайте ей достаточно подкачки, и не запускайте приложения, которые вдруг решают съесть огромное количество оперативной памяти, и у вас не возникнет проблем».
Он посвящен описанию сценария среды, в котором сверхкоммитирование и OOM killer не применяются или не действуют "по-настоящему" (если все приложения выделяют память по мере необходимости и имеется достаточно виртуальной памяти для распределения, записи в память будут следовать за распределением памяти без ошибки, поэтому мы не могли говорить о слишком загруженной системе, даже если была включена стратегия избыточной загрузки). Речь идет о неявном признании, что overcommit и OOM killer работают лучше всего, когда их вмешательство не требуется, что, насколько я могу судить, так или иначе разделяется большинством сторонников этой стратегии (и я признаю, что не могу сказать много ...). Более того, обращение к приложениям с определенным поведением при предварительном распределении памяти заставляет меня думать, что конкретная обработка может быть настроена на уровне распределения вместо использования по умолчанию,
Что касается JVM, то это виртуальная машина, в какой-то степени ей нужно выделять все ресурсы, которые ей нужны при запуске, чтобы она могла создать свою «поддельную» среду для своих приложений и держать свой доступный ресурс отдельно от хоста. среда, насколько это возможно. Таким образом, может быть предпочтительнее иметь сбой при запуске, а не через некоторое время как следствие «внешнего» состояния OOM (вызванного чрезмерной передачей / OOM killer / что угодно), или в любом случае страдать от такого условия, мешающего его собственному стратегии внутренней обработки OOM (как правило, виртуальная машина должна получать любые необходимые ресурсы с самого начала, а хост-система должна «игнорировать» их до конца, точно так же, как никогда не используется любое количество физической памяти, разделяемое с графической картой, - и не может быть - тронут ОС).
Что касается Apache, я сомневаюсь, что время от времени убивать и перезапускать весь сервер лучше, чем позволить одному дочернему элементу, а также одному соединению, потерпеть неудачу с самого начала (= дочернего / подключения) (как если бы это был совершенно новый экземпляр JVM, созданная после запуска другого экземпляра некоторое время). Я думаю, что лучшее «решение» может зависеть от конкретного контекста. Например, если рассматривать службу электронной коммерции, может быть гораздо предпочтительнее иметь иногда несколько случайных неудачных соединений с графиком покупок, чем потерять весь сервис, с риском, например, прервать текущее завершение заказа или (может быть, хуже) процесс оплаты со всеми последствиями дела (может быть, безвредным, но, возможно, вредным - и, конечно, когда возникли проблемы,
Точно так же на рабочей станции процесс, который потребляет наибольшее количество ресурсов и, таким образом, является первым выбором для убийцы OOM, может быть приложением с интенсивным использованием памяти, таким как транскодер видео или программное обеспечение для рендеринга, вероятно, единственное приложение пользователь хочет быть нетронутым. Эти соображения намекают на то, что политика OOM killer по умолчанию слишком агрессивна. Он использует подход «наихудшего соответствия», который как-то похож на подход некоторых файловых систем (OOMK старается освободить как можно больше памяти, уменьшая при этом количество уничтоженных подпроцессов, чтобы предотвратить любое дальнейшее вмешательство в короткие сроки, так как кроме того, fs может выделить больше дискового пространства, чем фактически необходимо для определенного файла, чтобы предотвратить дальнейшее распределение, если файл вырос, и, таким образом, в некоторой степени предотвратить фрагментацию).
Тем не менее, я думаю, что противоположная политика, такая как подход «наилучшего соответствия», могла бы быть предпочтительной, чтобы освободить точную память, необходимую в определенный момент, и не беспокоиться о «больших» процессах, которые вполне могут быть бесполезными. памяти, но также может и не знать, и ядро не может этого знать (хм, я могу себе представить, что отслеживание количества обращений к страницам и времени может подсказать, если процесс выделяет память, он больше не нужен, так что угадать, является ли процесс тратит память или просто использует много, но задержки доступа должны быть взвешены на циклах процессора, чтобы отличить потерю памяти от памяти и интенсивное использование процессора, но, хотя это может быть неточным, такая эвристика может иметь чрезмерные издержки).
Более того, может быть неверно, что убийство меньшего количества возможных процессов - это всегда хороший выбор. Например, в среде рабочего стола (для примера давайте подумаем о неттопе или нетбуке с ограниченными ресурсами) пользователь может запустить браузер с несколькими вкладками (таким образом, он потребляет память - допустим, это первый выбор для OOMK) плюс несколько других приложений (текстовый процессор с несохраненными данными, почтовый клиент, программа для чтения PDF, медиаплеер, ...), плюс несколько (системных) демонов, а также несколько экземпляров файлового менеджера. Теперь происходит ошибка OOM, и OOMK решает убить браузер, пока пользователь делает что-то, что считается «важным» в сети ... пользователь будет разочарован. С другой стороны, закрытие нескольких файловых менеджеров
В любом случае, я думаю, что пользователь должен иметь возможность самостоятельно принимать решение о том, что ему делать. В настольной (= интерактивной) системе это должно быть относительно легко сделать, при условии, что зарезервировано достаточно ресурсов, чтобы попросить пользователя закрыть любое приложение (но даже закрытия нескольких вкладок может быть достаточно) и обработать его выбор (вариант может состоят из создания дополнительного файла подкачки, если места достаточно). Что касается сервисов (и вообще), я бы также рассмотрел еще два возможных усовершенствования: одно - протоколирование вмешательств OOM-убийцы, а также процессы, запускающие / блокирующие сбои, таким образом, что сбой может быть легко отлажен (например, API может информировать процесс, инициирующий создание нового процесса или разветвление - таким образом, такой сервер, как Apache, с соответствующим патчем, может обеспечить лучшую регистрацию для определенных ошибок); это может быть сделано независимо от предпринимаемых сверхкоммитов / OOMK; во-вторых, но не для важности, можно было бы создать механизм для точной настройки алгоритма ООМК - я знаю, что возможно, в некоторой степени, определить конкретную политику для процесса в отдельности, но я бы хотел «централизованный» механизм конфигурации, основанный на одном или нескольких списках имен приложений (или идентификаторов) для идентификации соответствующих процессов и придания им определенной степени важности (согласно перечисленным атрибутам); такой механизм должен (или, по крайней мере, мог бы) также быть многоуровневым, чтобы мог быть пользовательский список верхнего уровня, системный (распределение) определенный список и (нижний уровень) определенные пользователем записи (так например, файловый менеджер DE может дать OOMK команду безопасно уничтожить любой экземпляр,
Более того, API может быть предоставлен для того, чтобы позволить приложениям повышать или понижать свой уровень «важности» во время выполнения (с точки зрения управления памятью и независимо от приоритета выполнения), так что, например, процессор Word может запускаться с низкая «важность», но повышайте ее, поскольку некоторые данные хранятся перед сбросом в файл, или выполняется операция записи, и снова снижаете важность, когда такая операция завершается (аналогично, файловый менеджер может изменить уровень, когда он передается из простого использование файлов для работы с данными и наоборот вместо использования отдельных процессов, и Apache может дать разные уровни важности различным дочерним элементам или изменить дочернее состояние в соответствии с некоторой политикой, выбранной системными администраторами и раскрытой через Apache - или любой другой тип сервера. - настройки). Конечно, такой API может и будет злоупотреблять / злоупотреблять, но я думаю, что это небольшая проблема по сравнению с тем, как ядро произвольно убивает процессы для освобождения памяти без какой-либо соответствующей информации о том, что происходит в системе (и о потреблении памяти / времени создания или подобной области). «не достаточно релевантен или« проверяет »для меня) - только пользователи, администраторы и составители программ могут реально определить, является ли процесс« по-прежнему необходимым »по какой-то причине, какова причина и / или находится ли приложение в ведущем состоянии к потере данных или другим повреждениям / проблемам, если их убить; тем не менее, можно сделать некоторое предположение, например, поиск ресурсов определенного типа (файловые дескрипторы, сетевые сокеты и т. д.), полученных процессом, и с ожидающими операциями может сказать, должен ли процесс находиться в более высоком «состоянии», чем один набор,
Или просто избегайте чрезмерной загрузки и позвольте ядру делать то, что должно делать ядро, выделяя ресурсы (но не спасая их произвольно, как это делает убийца OOM), планируя процессы, предотвращая голодание и взаимные блокировки (или спасая от них), обеспечивая полное прерывание и разделение памяти, и так далее ...
Я также потратил бы еще несколько слов о подходах сверхкоммитов. Из других обсуждений я высказал мысль о том, что одна из основных проблем, связанных с чрезмерной фиксацией (как причина этого хотеть, так и источник возможных проблем), заключается в обработке вилок: честно говоря, я не знаю, как именно Стратегия «при записи» реализована, но я думаю, что любая агрессивная (или оптимистичная) политика может быть смягчена с помощью стратегии локального обмена. То есть вместо простого клонирования (и настройки) разветвленных кодовых страниц процесса и структур планирования можно скопировать несколько других страниц данных перед фактической записью, выбрав среди этих страниц родительский процесс, к которому более часто обращались для записи (то есть использование счетчика для операций записи).
Всё, конечно, ИМХО.
источник
/proc/$PID/oom_adj
./proc/$PID/oom_score_adj
Кредит: - Ядро Linux запускает убийцу OOM
источник