Pull to refresh

Comments 18

Подскажите в линуксе как и в виндовс? когда 30 гб ФИЗИЧЕСКОЙ памяти свободно, но вылетает OUT OF MEMORY при попытки открыть любую новую вкладку, хотя и текущие могут крашнутся

У меня в линуксе 62гб свободно, ничего не вылетает.

У вас, похоже, своп отключен? Обратите внимание на строчку «выделено» — это значение не может превышать объём ОЗУ + свопа, и у вас оно близко к максимуму. Винда не умеет нормально работать в таких условиях (не уверен, что Linux умеет). Для подробностей нужно гуглить «commited memory» и «windows without swap».

Линукс умеет несколько режимов работы с памятью, которая может быть выделена, но не занята. По-умолчанию — выделить можно сколько угодно. Но можно и включить режим "сколько есть, столько и выделяем, не больше" с возможным коэффициентом типа "выделяем не более 200% доступного".

нет, винда не оверкоммитит вообще. сколько есть оперативки+свопа, столько закоммитить и можно. в отличие от линукса, в котором вон хром больше терабайта на процесс коммитит сходу.

добавь свопа, гигов 30-50. физической записи в него не будет, но в нем можно будет выделять страницы и не упираться в лимит так быстро. а еще неплохо бы посмотреть, кто там накоммитил и открутить погромисту этого руки.

Диагноз “Out of Memory” не имеет отношения к Physical RAM.

Например, если администратор для конкретного юзера/процесса/группы установил лимит в 1GB RAM, то у ОС может быть свободным хоть терабайт физической памяти, но тот юзер/процесс/группа умрёт с диагностикой “Out of Memory.”

Отложенное выделение

Про это я бы мог подробнее рассказать с точки зрения оптимизаций, так как сталкивался с этим на практике. Когда память выделяется (даже обычным malloc, если большой буфер), то при первом использовании будут page fault исключения на каждой выделенной странице, что может ощутимо влиять на производительность. Каждые 4кб происходит исключение, система его обрабатывает очищая память. Очистить память быстро, но исключения не быстрые (у разных архитектур и ОС время обработки может варьироваться, но исключения в любом случае затратные). Кроме того, при обработке исключений теряется часть кэша. Поэтому часто выделять и освобождать большие области памяти - это плохая идея, если вы обрабатываете поток данных, то лучше один раз выделить большой буфер и держать открытым. Хотя это вредно для доступности памяти, но если у вас игра или обработка видео - то это может быть оправдано.

Спасибо вам большое!

Так lazy commits придуманы были для оптимизации работы системы в целом, а не отдельно взятого приложения. А для оптимизации отдельно взятого приложения придуманы были механизмы фиксации страниц в физической памяти (тот же mlock()). Эти две техники — естественные антагонисты. Первая позволяет программисту не париться, ценой вероятных (но не обязательных, зависит от загрузки системы) потерь времени на обработку page faults, а вторая заставляет париться ручным управлением в угоду производительности конкретного приложения.

Разумный баланс всегда где-то посередине и подразумевает отчётливое понимание этого конфликта, механизмов управления памятью в ОС, и трезвой оценки потребностей разрабатываемого приложения. Проблема как раз в том, что многим начинающим горе-оптимизаторам присуще считать, что именно их приложению требуется постоянная RAM-резидентность, а то, что профайлер покажет, что их оптимизации сэкономили аж целых 200μs при 15 минутах общего рантайма, они не увидят — профайлером пользоваться ещё не научились. Это как раз те случаи, которые Д. Кнут и назвал premature optimizations.

Строго говоря оба параметра vm.dirty* непоняты и неверно поданы. Первый "vm.dirty_expire_centisecs" ничего не сбрасывает. Он только помечает данные к сбросу (как устаревшие). Периодически флашер (он работает параллельно) проверяет, какие данные помечены устаревшими и сбрасывает их на диск. У него своя настройка периодичности "vm.dirty_writeback_centisecs". Из коробки 5 секунд, но можно и час поставить. Тогда данные будут сбрасываться каждый час, а не когда там "vm.dirty_expire_centisecs" что-то пометил. Второй "vm.dirty_ratio" вообще с флашем не связан. Он определяет максимальный размер буфера. Когда мы добираемся до него - запись становится синхронной постоянно блокируясь пока диск что-то пишет. Флашинг начинается сильно раньше этого и его контролирует "vm.dirty_background_ratio". И он не может быть больше половины "vm.dirty_ratio". Т.е. флашинг начинается не тогда, когды мы вбрали весь буфер, а сильно заранее, где-то при заполнении на половину или даже ещё раньше.

Хмм, не знал. Спасибо за уточнения, в ближайшее время исправлю

Подскажите, как так получилось, что часть текста полностью соответствует части текста из статьи Управление памятью в Linux? Да, это перевод, но неужели Вы перевели точь-в-точь как я и даже допустили опечатку точь-в-точь, как у меня (см. «Система страница»)?

Такс, видать когда переносил старую статью, забыл добавить источник.

Это статья - ремейк давней статьи, и когда я проверял перед публикацией через антиплагиат, мне Ваша статья почему то не попалась.

Извиняюсь, в следующий раз буду внимательнее.

Также можно включить zram

Во многих линуксах по умолчанию уже включен zswap, и включать zram скорее всего не нужно (а включать его одновременно с zswap вообще вредно)

Сорри за занудство, но вот в этом абзаце какой-то нонсенс, контрастирующий с декларируемым "сложным" уровнем статьи:

Основной единицей хранения данных в памяти является двоичный разряд, который называется битом. Считается что некоторые компьютеры используют и десятичную, и двоичную арифметику, но это не так. Они используют двоично-десятичный код. Для хранения одного десятичного разряда задействуют 4 бита. Эти 4 бита дают 16 комбинаций для размещения 10 различных значений (от 0 до 9). При этом 6 остальных значений не используется. В двоично-десятичном представлении 16 бит достаточно для сохранения числа от 0 до 9999, то есть доступно 10000 комбинаций. А если бы те же устройства использовались для хранения двоичных чисел, они могли бы содержать всего 16 комбинаций.

Во вводной никак не указано, что речь идет о хранении рациональных чисел в двоично-десятичном (BCD) формате. То есть выглядит так, что этот формат используется для хранения любых значений, в том числе для целых чисел, но это же не корректное утверждение! Целые типы (byte, int и пр.) как правило хранятся в двоичном коде, используя все комбинации в заданном для хранения числе байт (с учетом бита на знак конечно).

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

А вот эта последняя фраза вообще ставит в тупик, я не понимаю что автор хотел сказать, т.к. для 16 бит в двоичном коде можно сохранить 65536 комбинаций.

Эти вводные абзацы явно расчитаны на новичков, чтобы вообще не знающий устройства компьютерной памяти человек понял суть, поэтому видимо знающие читатели просто скипнули эти абзацы ничего не заметив :) Но реально описание в таком виде введет в заблуждение и даст человеку неверное понимание!

Ещё опечатка в статье:

Существуют два типа ОЗУ — статистическое и динамическое. Статистическое ОЗУ (SRAM) конструируется с использованием D-триггеров.

Static RAM -- статическое ОЗУ. Не статистическое. @DrArgentum, поправьте пожалуйста.

Общее впочатление: статья очень детально описывает работу с памятью и вторая её половина касается нетривиальных аспектов реализации, но выглядит так, что вводную часть поручили нейросети ;)

Спасибо вам большое, в ближайшее время исправлю. Вводная часть в основном писалась, когда я начал читать Таненбаума, устройство компьютера.

Sign up to leave a comment.