LINUX.ORG.RU
ФорумTalks

Линукс ядро не может мягко обрабатывать ситуации с нехваткой памяти

 , , ,


4

3

На Reddit уже почти полтысячи комментариев по поводу проблемы в Линукс ядре: оно не может мягко обрабатывать ситуации с нехваткой памяти.

Оригинальное сообщение в LKML:

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

Шаги:

1) Загружаемся с параметром mem=4G
2) Выключаем поддержку swap (sudo swapoff -a)
3) Запускаем любой веб браузер, например, Chrome/Chromium или/и Firefox
4) Начинаем открывать вкладки с сайтами и смотрим как уменьшается объём свободной памяти

Как только возникает ситуация, что новая вкладка требует больше оперативной памяти, чем доступно, система практически полностью зависает. Вы даже с трудом сможете двигать курсором мыши. Индикатор жёсткого диска будет моргать без остановки (мне не ясно почему). Вы не сможете запустить новые приложения или закрыть текущие запущенные.

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

Я почти уверен, что можно поменять некоторые параметры sysctl, чтобы избежать подобную ситуацию, но что-то подсказывает, что это можно сделать по умолчанию для всех, потому что нетехнические пользователи, столкнувшись с такой проблемой, просто откажутся от использования Линукс и им будет не того, чтобы искать решения в Google.

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

Подробности

Перемещено Shaman007 из linux-general

anonymous

Читаю тему и хочу сказать:

Тупые линуксойды одержимые надсмешками над пользователями не могут себе RT ядро поставить.

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

Ну так что стоит решить проблему с поздним приходом OOM? Достаточно при отключённом свопе запретить сброс неанонимных страниц.

KivApple ★★★★★
()
Ответ на: комментарий от i-rinat

что делает Windows, если отключить своп вообще? Она создаёт своп-файл сама

Круто. Вот где настоящая забота о дураках пользователях.

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

Меня скорее удивляет, что никто до сих пор не вспомнил, что примерно для сабжевых ситуаций уже придумали Low Memory Killer, которым вполне себе пользуется Андроид (оно и понятно — на телефонах-то со свапом обычно дела так себе, да и пропускать звонок или будильник из-за выжравшего память хрома не комильфо).

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

Вышел Иван-дурак с Ccleaner'ом наперевес и давай с виндою биться. Рубанул по реестру — глядь, а на месте старого куста новые выросли, да трижды по три ветви в каждом. Вычистил TMP — а она винапдейт запустила да заново забила его по самый край, так что ввек диск не отдефрагментируешь. Удалил свопфайл — а у неё новый отрастает, каждый спрятан пуще предыдущего да своппинесс растёт сама как на дрожжах, хоть вообще оперативку вытаскивай.
Плюнул Иван да и купил себе мак. Раз хотел чегой-то по старой привычке соптимизировать — да молвила ему Сири человечьим голосом: не трогай, мол, пригожуся ещё, — и в ту же секунду подогнала лубков заморских с мужеложцами, у которых по усам текло, да в рот не попало.

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

Смотри: есть память -> запускаем браузер -> он сжирает всю память -> нужно отрисовать новый UI элемент -> требуется память -> памяти нет. Что делать-то?

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

Однажды я решил опробовать клон wrk на Go, натравив его на рукописный веб-сервер, который отдавал несколько гигабайт в секунду, читая их из tmpfs, но клон оказался написан рукожопом и отданное веб-сервером оставалось в оперативе, по крайней мере на какое-то время. Только я запустил, а все 16гб оперативы оказались выжраны (был запущен htop, который несоклько секунд ещё ворочался), тут же подоспели и быстрые 8гб свопа на Samsung 960 Evo. Система встала колом и не отвисала несколько минут, пока тест успешно, хз каким чудом, не закончился, ничего убито не было.

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

Вот офтопик вешается просто по процессору и по IO на раз-два. Я вот эти самые строки пишу из-под Windows 10, где запустить жручее-неуправляемое - прямой путь к хард-резету, да еще и с потерей буферов записи (то есть вводу ключа восстановления Bit Locker'а на ребуте).

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

Иметь лимит на такой случай для работы gui оболочки, независимый от остального софта

Шик. Как ядро отличит gui оболочку от не гуи оболочки? Какого размера должен быть пул? Что делать, если гуи программ слишком много?

kirk_johnson ★☆
()
Последнее исправление: kirk_johnson (всего исправлений: 1)

Shaman007
я конечно понимаю что ты топишь за RHEL и вообще линукс прекрасен

но

если посмотреть в корень

вся эта хрень вызвана оптимистическим поведением malloc(), который никогда не возвращает NULL
потому что хреново написанный софт не умеет самостоятельно эффективно управлять своими ресурсами

и вообще потому что любители (среди которых и glibc который реализовывает таким образом malloc) поделать mmap(NULL, STOPICOT_MEGABAYT_OT_JVM, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS |, -1, 0); будут страдать от невозможности проверить доступна ли память или нет, и при попытке записи в регион для которого невозможно выделить страничку физической памяти начинается адовый трешак.

оом-киллер срабатывает гораздо позже, ибо ядро будет предпринимать тщетные попытки освободить mmap()-ed regions that were backed by disk files всё равно не освободят достаточно памяти ибо процесс с вкладкой в браузере будет жрать всё больше и больше
хуже всего когда ядро освобождает файлы которые backed by disk files являются кодом из shared libraries и всё адово глючит-лагает

А оом-киллер всё еще не запускается.

В общем.

Я вижу 2 варианта которые надо предпринимать для решения этой проблемы:

1) Граждан которые не осиливают брать ровно столько памяти сколько нужно и делать realloc() в случае чего с КОРРЕКТНОЙ проверкой return value следует наказывать публичным позором и тыканием пальцев
Граждан которые не проверяют malloc() == NULL вообще гнать ссаными тряпками (привет гномосекам)
2) Когда процесс занимает дополнительные страницы памяти, которые были получены с помощью mmap() и этим самым количество свободных ФИЗИЧЕСКИХ страниц памяти подходит к границе, когда память заканчивается - ядро приостанавливает его работу (примерно так же как оно это делает и сейчас, но минуя дебильные попытки освободить mmap()-леную память потому что это приведёт к адскому лагодрому который мы и пытаемся решить) и срабатывает oom-killer, спокойно убивая виновника. Либо уведомляя ОС (если имеется какой-то интерактив с пользователем, например граф. оболочка) что память заканчивается (тогда границу стоит поставить подальше).

Если память получена с помощью malloc() то спокойно возвращать NULL. Дауны которые не проверяют на NULL идут нахрен.

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

Это все прекрасно, но что делать, если память сожрали, а гуй рисовать нужно? Вот запущена у тебя пежня на nodejs (привет, слак), и чо делать?

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

что делать, если память сожрали

процесс который сожрал память будет висеть

остальные процессы рисуют гуй как тебе нужно и используют тот остаток памяти что еще есть - этого хватит чтобы показать тебе окошо «ОЛОЛО, ЧУВАК, ПАМЯТИ НЕТ - ПОКАЖИ КОГО УБИТЬ И Я СДЕЛАЮ ЭТО СЕЙЧАС!» со списком возможных жертв

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

остальные процессы рисуют гуй как тебе нужно и используют тот остаток памяти что еще есть - этого хватит чтобы показать тебе окошо «ОЛОЛО, ЧУВАК, ПАМЯТИ НЕТ - ПОКАЖИ КОГО УБИТЬ И Я СДЕЛАЮ ЭТО СЕЙЧАС!» со списком возможных жертв

А с чего вдруг хватит-то? Там таких программ штук двадцать, медиаплеер пытается играть, какой-нибудь man-db заново индексирует диски, sshd пытается не помереть и хоть что-то в сеть отдать... Короче, я не понимаю, с чего ты взял, что память будет вот прям щас. А если память будет не вот прям щас, а через пару секунд, то мы имеем то, что имеем сейчас.

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

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

разницу между

подходит к границе, когда память заканчивается

и

памяти нет

чувствуешь?

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

Нет, не чувствую. Потому что на практике это однозначает то же самое: памяти начинает адово нехватать, и все рвут куски на себя. Относительно рабочим решением было бы сделать LOW-LATENCY бирку на тред, означающую, что вот ему памяти нужно дать первее всех. Но если таких процессов опять окажется столько, что памяти на всех перестанет хватать, начнется рак.

Алсо да, убивать виновника OOM это особая дисциплина, в которой бегают уже лет лет двадцать, и никак не могут нормально. Ну и конечно, убивать рабочий процесс (прикинь, ты считаешь работу на ляптопе, и регулярно уходишь в своп), результат которого может быть более важным, чем отсутствие лагов — это прям гениально.

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

Нет, не чувствую

твои проблемы

Потому что на практике это однозначает то же самое: памяти начинает адово нехватать

память есть для всех кроме того кто её слишком много жрёт

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

будешь делать таблицы с исключениями кому давать а кому нет для десктопных систем?

Ну допустим ты дал Xorg-у память. Окей, но чтобы нарисовать окошко которое тебя уведомит о нехватке памяти может одного Xorg недостаточно? Дашь бирку гномощели? А если гномощешь течёт?

А если Xorg течёт из-за баганых дровишек?

Но вообще мысль интересная. Попробуй реализовать - авось получится годно.

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

память есть для всех кроме того кто её слишком много жрёт

До очередного открытого nodejs приложения.

будешь делать таблицы с исключениями кому давать а кому нет для десктопных систем?

Нет, не буду, эта идея заранее ущербна. Как и попытки прибить рандомный процесс, который больше всех памяти съел. Это прикольная тема на серверах, где отказоустойчивость, резервирование и прочая бла-бла-бла. Когда ты третий час обсчитываешь 3D модель, а потом все ВНЕЗАПНО падает к хренам, потому что твоя ОСЬ ВНЕЗАПНО решила тебе «помочь»... это как-то мерзотно.

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

До очередного открытого nodejs приложения.

Нет. malloc() == NULL для всех новых запросов всем прогам. И очередное nodejs приложение просто не стартанёт

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

Нет. malloc() == NULL и очередное nodejs приложение просто не стартанёт

А, ну супер. То есть я даже терминал не смогу запустить. Чувак, да ты просто гений UX.

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

То есть я даже терминал не смогу запустить.

у тебя будет окошко которое предложит кого убить, тебе мало?

Чувак, да ты просто гений UX.

Я свой вариант предложил. Рабочий. А ты предложил заранее ущербную идею.

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

у тебя будет окошко которое предложит кого убить, тебе мало?

Да, что делать, если все процессы либо нужные, либо жрут мизер?

Я свой вариант предложил. Рабочий. А ты предложил заранее ущербную идею.

Нет, обе эти идеи одинаково ущербны. Просто в разных местах.

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

А что делать, когда у нас память сожрало что-то, что само юзерспейс-гипервизор с кучей процессов? Хром, например, ЕМНИП, так и работает, не?

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

Подключитесь по SSH и прибейте руками еще. У них не такие-то требования к памяти, всегда работало.

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

Но! 4ГБ памяти + приложение, которое заведомо больше ее жрет - своп == выстрел в колено. Не надо так.

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

жрут мизер?

отмечать галочкой кого убивать

что делать, если все процессы нужные

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

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

Просто в разных местах.

моё вот решает проблему от которой горит челик в ОП посте на реддите. Когда браузер сжирает память у тебя зависает ВСЁ. У тебя есть возможность решить эту проблему без нажимания на кнопку reset

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

malloc(), который никогда не возвращает NULL

4.2, я проверял. Но действительно редко.

У него и нет особых причин вернуть NULL, потому что он не выделяет память.

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

А что делать, когда у нас память сожрало что-то, что само юзерспейс-гипервизор с кучей процессов? Хром, например, ЕМНИП, так и работает, не?

Так я о том же.

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

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

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

Так этот пирожок 20 лет едят со всех сторон. Он с говном. Делать статическую разметку части памяти (как в венде) тоже не решает все вопросы и создает новые.

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

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

И нет, В ВЕНДЕ ЭТО ДОФИГА ВООБЩЕ ПРОБЛЕМА.

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

собственно, тут нужно авторитарно-виндовое поведение - прибивать жирные программы нафиг. тут не критичные задачи - можно и погрохать.
главное, дать юзеру возможность настроить этот выбор, либо валим программы, либо программы важны и даём ставить ОС раком.

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

Его сложнее замучить и как правило удаётся вовремя заметить и перейдя в консоль принять меры через htop.

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

Нет, не чувствую. Потому что на практике это однозначает то же самое: памяти начинает адово нехватать, и все рвут куски на себя.

ну значит надо пересмтреть лимит «подходим к границе».
это он раньше был, скажем 1 мб ОЗУ в годы вин98. теперь это должно быть 1000. потом что стольник любая вкладка выжрет за милую душу.
и если памяти меньше 1 гб, то и грохать жирноту.

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

Еще раз — если результат работы жирноты для пользователя важнее отзывчивости, скажет ли он тебе спасибо? Что делать, если жрут помалу, но много процессов?

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

Еще раз — если результат работы жирноты для пользователя важнее отзывчивости, скажет ли он тебе спасибо?

надо дать возможность хотя бы настраивать этот выбор. то есть включать и выключать.


Что делать, если жрут помалу, но много процессов?

ну всё равно же видно, кто жрёт чуть больше и с кого начинать Освенцим.

darkenshvein ★★★★★
()

На самом деле, решение простое - общий лимит на потребление памяти для всех процессов, запущенных не от рута и не входящих в число заранее избранных (оболочка ДЕ, иксы и т.п.).

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

Должна сообщить приложению, которое запрашивает больше памяти, чем есть, что все, приехали, памяти больше нет.

cvs-255 ★★★★★
()
Ответ на: комментарий от Shaman007

Во-первых, процесс с наибольшим количеством памяти убьет OOM-killer

Или не убьет

cvs-255 ★★★★★
()
Ответ на: комментарий от Stanson

Если в линуксе можно из консольки или удалённо прибить урода

Так не получается ничего прибить из консольки. Потому что все встало намертво

cvs-255 ★★★★★
()
Вы не можете добавлять комментарии в эту тему. Тема перемещена в архив.