Как стать автором
Обновить

Комментарии 102

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

Так вот весь смысл в том, что если вы сидите без свапа но ООМ ещё не пришел (а это вполне себе реально если у вас куча фтапаков/снапов которые используют «принесенное с собой» а не системное окружени, то вы пойдете пить чай. А мифические «тормоза из-за свапа» выражаются в которотких подлагиваниях при переключении в другое приложение, и только.

Я не про "тормоза из-за свапа" говорил, а про неотзывчивость в экстремальных ситуациях. У меня памяти в системе достаточно, поэтому поведение "fail fast" для меня предпочтительнее.

Вы неправильно поняли прочтенное — прежде чем у вас случится «fail fast» у вас всё начнет лагать, потому что с точки зрения систему ресурсы еще есть — и этот ресурс это страницы кэша, который можно дрогнуть и отдать под данные. А потом когда данные понадобятся поднять их снова с диска.

Тест с отключённым свапом это очень хорошо показывает — процесс едва-едва шевелится и затормозил десятикратно.

Если вы хотите «fail fast» — вам надо включать лимиты на cgroup и механизмы ulimit. И активировать ограничения на размер закоммиченой памяти (overcommit ratio).

Ну вот, кстати, такой вариант:


# swapoff -a
# time tail -f /dev/zero
Killed

real    0m2,152s
user    0m0,211s
sys     0m0,777s
root@khajiit-t440:~# swapon -a
root@khajiit-t440:~# time tail -f /dev/zero
Killed

real    0m10,810s
user    0m0,701s
sys     0m7,286s

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


В случае, если приложению таки нужны отсвопленные данные — на примере Daz3D, отъевшего под вайном 20ГБ (из 24 наличных) памяти и столько же свопа, скорость обработки падает в тысячи раз в неудачном случае и в десятки — в удачном, по сравнению с отсутствием своппинга.
Но тут деваться некуда, потому что память реально нужна в таком количестве, и ее реально нету столько, сколько надо.


При этом система постоянно сношает своп на чтение и запись, потому что чтобы вынуть данные из свопа надо свободную память, а ее нет.

При этом система постоянно сношает своп на чтение и запись, потому что чтобы вынуть данные из свопа надо свободную память, а ее нет.

Малый размер порождает много паразитного I/O (аналог трэшинга). Особенно если у вас большой объем неизменяющихся данных. Если у вас программа отъедает 40GB при 24 наличных, то свап вам нужен 48 а не 24.

24GB сложно назвать малым размером…
А самое замечательное в том, что акция оказалась разовой за лет, наверное, 7.

Я уже объяснял — если данные редкоменяющиеся — свап превращается в аналог разделяемой библиотеки — страницы уезжают в свап из оперативной памяти и освобождают её, но когда страница погружается из свапа, она оттуда не выкидывается. Это позволяет не сбрасывать её в свап повторно если она не изменилась.
Сбросили страницу в свап.
Понадобилась — прочли из свапа.
Стала не нужна и не менялась — просто дропнулась из памяти.
Стала второй раз нужна — снова поднялась из свапа.
Изменилась — оторвалась от свапа, место в свапе пометили как «незанятое».
Чтобы этого «повторного использования» достичь, надо всю запись в свап делать в свободное место. А это значит, что свап должен быть «достаточно большим» чтобы всегда можно было записать в это самое «свободное место».
Так вот весь смысл в том, что если вы сидите без свапа но ООМ ещё не пришел
Со свапом кроме OOM нужно учитывать и быстродействие этого свапа, а так же то, что этот OOM может не придти вообще, в том случае если потребление памяти близко к максимально возможному, но не превышает его.
А мифические «тормоза из-за свапа» выражаются в которотких подлагиваниях при переключении в другое приложение, и только.
И чем вы тогда объясните полное отсутствие перерисовки экрана в течении получаса?

Т.е. проблема очевидна — система пытается трактовать память, занятую библиотеками, как "условно свободную" и с радостью выгружает эти библиотеки, чтобы впихнуть на их место данные. И когда вся память оказывается занята данными, то вернуть обратно эти библиотеки уже некуда (а вернуть их придется, т.к. нужен код, чтобы его выполнить). И вместо того, чтобы прикидываться, словно у нас есть этот "условно свободный" гигабайт, ими занятый (на самом деле нет), нужно просто запретить такую выгрузку. Есть такой флаг в Linux?

система пытается трактовать память, занятую библиотеками, как «условно свободную» и с радостью выгружает эти библиотеки, чтобы впихнуть на их место данные

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

И придет ООМ. И похоронит какой-нибудь процесс. Например, дисплейный сервер, который обратился к системе «дай мне двойной буфер размером 3840x2060x32». Или клиента этого дисплейного сервера который получил ссылку на этот буфер и начал в него рисовать (а значит активно потреблять память).
Есть такой флаг в Linux?

man mlock/man mmap на предмет MAP_LOCKED. Но вам этот флаг не нужен. Он породит совершенно внезапные сегфолты в условиях memory pressure.
система начинает дропать кэши (которые совсем не ненужные кэши, а очень даже наоборот).

Вот я и говорю, что если "очень даже наоборот", зачем их дропать? Они не должны выгружаться. А выгружая, вы как раз и притворяетесь, что они неважные.


И придет ООМ.

При наличии свопа он тоже придет, только позже, после того, как система повисит. А если конец одинаков, то зачем его оттягивать?


Например, дисплейный сервер, который обратился к системе «дай мне двойной буфер размером 3840x2060x32»

Мне кажется, мы спорим совершенно о разном. Я и многие другие на хабре говорят, что если у вас достаточно памяти, чтобы "двойной буфер размером 3840x2060x32" влез в память, то своп вам не нужен. Если недостаточно — то конечно нужен. А ваша позиция в том, что своп нужен всегда, на тот гипотетический случай, когда в системе вдруг не станет хватать памяти. И насколько я понял из ваших объяснений, система может писать в своп даже если памяти достаточно (как было у одного из комментаторов в прошлой статье — 64 Гб незанятой памяти и своп 4 Гб). Да, может система и не читает из свопа, потому что это просто копия того, что есть в памяти, выгруженное туда на всякий случай (а вдруг памяти не станет хватать? А у нас тут уже резервная копия выгружена, сможем быстро освободить память).


Но при работе системы раз за разом оказывается, что нужды читать из свопа нет и нет (памяти же еще много), а вот писать все равно приходится — ведь сделанный туда "бекап" устаревает и его приходится заменять. Что это, как не безсмысленные действия?


man mlock/man mmap на предмет MAP_LOCKED. Но вам этот флаг не нужен. Он породит совершенно внезапные сегфолты в условиях memory pressure.

Тут больше интересовал флаг, позволяющий делать это без перекомпиляции программ, по аналогии с vm_swappines. А условия memory pressure могут и не наступить никогда

как было у одного из комментаторов в прошлой статье — 64 Гб незанятой памяти и своп 4 Гб

Там «было» только слова. Ни выводе free, ни шапки топа процессов по памяти. Поэтому не вижу смысла о чем-то там гадать. И то у там vm_swappiness=0, то уже 1. Гадать так это то же самое, что ставить диагноз на основании СМС написанных со слов услышанных в скайпе.

"Если вы не хотите, чтобы система использовала свап — добавьте ей памяти но не отключайте свап."


Хороший совет )
Если система своя, то ты и так отдашь ей всю память.
А если ты ее покупаешь, то продавец тебе её даром не даст. Хоть для свапа хоть под оперативку.

Я пробовал по разному. На ноутбуке было 8ГБ оперативной памяти и я часто запускаю различные приложения на Java. В итоге результат получился такой:


  1. Использование swap на SSD позволяет компьютеру прилично работать до поры до времени. Потом появляются фризы, которые уйдут только после перезагрузки системы. Да и SSD лучше от этого не становится.
  2. Отключение swap. Фризы пропадают, но иногда может возникнуть ситуация, что система просто встаёт колом и почти не реагирует ни на что. Обычно в таких случаях я просто перезагружал систему жёстко. Это явно не нормально.
  3. Использование zram. На этом варианте я и остановился. За одно прикупил дополнительной памяти. Пришлось заменить, т.к. слотов не было, но 16ГБ мне уже хватает. Теперь ни фризов, ни зависаний нет.
НЛО прилетело и опубликовало эту надпись здесь
Я подсмотрел такой вариант.
#!/bin/sh
echo 3 > /proc/sys/vm/drop_caches
swapoff -a && swapon -a

Естественно через sudo.
На opennet рекомендуют даже так: sync && sync && echo 3 > /proc/sys/vm/drop_caches
Фризы пропадают, но иногда может возникнуть ситуация, что система просто встаёт колом и почти не реагирует ни на что

А это типа не фриз?! Какая-то странная логика — «фризов нет но иногда всё встает колом».
Использование zram. На этом варианте я и остановился

И про этот кейс я также рассказал в конце. zram хорошо помогает в сочетании с обычным swap, иначе, в случае несжимаемых страниц, он даже добавляет тормозов.

Я рассказал о своём опыте.


А это типа не фриз?!

Фриз, это просто кратковременное подвисание на долю секунды. В запущенных случаях, довольно часто, но работать можно. Если свопа нет, то дождаться работоспособности системы после повисания практически невозможно.


И про этот кейс я также рассказал в конце. zram хорошо помогает в сочетании с обычным swap, иначе, в случае несжимаемых страниц, он даже добавляет тормозов.

Ну и хорошо. А я не стал насиловать свой SSD. Да и без этого работает. Уже пол года проблем не замечал.
P.S. Если честно, если бы была возможность воткнуть за адекватные деньги в 2 раза больше памяти, то я бы раскошелился. Но у меня пока, кроме варианта с существующим ноутбуком больше 16ГБ ставить неразумно, если, вообще, возможно. Не помню сколько ему лет, но я на нём обновляли Windows 8 до 8.1 после её выхода.

Подождите-подождите… А почему вы, когда говорите, что «памяти достаточно» считаете только память под «данные», но не под «код» (коего у вас, на минуточку, 3 ГБ). Разумеется, в сумме код + данные = 17 ГБ в 16 ГБ памяти не влезают, а бегаете вы там по всему куску. А со swap’ом у вас суммарной памяти как минимум, 32 ГБ (судя по выводу top’а). Проводите уж тогда тест в равных условиях, добавив памяти к варианту «без swap’а» до 32 ГБ. Тогда и будет вам вариант «памяти достаточно».

Вот именно и несмотря на коментарии к предыдущей статье автор пишет "добавьте оперативки и не отключайте своп" и не пишет даже в качестве варианта "добавьте до 64 Gb (для этого случая-теста) оперативки и отключите своп".
Это как в старом анекдоте "евреи не жалейте заварки" :) !

Посмотрите на последний пример top. Если бы я не показал исходников программы — что бы можно было подумать? Ну конечно же — линукс свапится и тормозит хотя свап отключен и у него море кэша, добавил еще 16ГБ и всё полетело, вот такой он глючный этот ваш линукс.

Я и вижу, что практически вся память занята кэшем/буферами (это, я так понимаю, как раз mmap и есть), 331 МБ — это, видимо, система и остальные 216 процессов, непонятно конечно, почему 175 МБ никуда не приткнули, но погоды это всё равно не делает — памяти явно недостаточно для всех «данных» + «кода», ведь вам надо 17 ГБ, которых просто нет.

Сначала у меня бомбануло, но вижу, что уже задают автору правильные вопросы. Совершенно согласен. Или можно наоборот, пусть автор выделит кусок оперативы для swap, и будет быстро и безопасно. Мы просто не маемся дурью и пропускаем эти брачные танцы со swap в RAM, а предпочитаем использовать всю, но следить за утилизацией. Сразу видно кто не кодил на Си)
А ООМ киллер, убивший вкладку хрома — крайне специфичный кейс, поскольку киллер не всё подряд убивает, а по рейтингу, который он составляет исходя из user time процесса, cpu time и прочего.
К тому же, память иначе выделяется, где же кучи, чанки, арены? Причём одна арена обслуживается одним cpu потоком. И т.д.
https://sourceware.org/glibc/wiki/MallocInternals

К тому же, память иначе выделяется, где же кучи, чанки, арены?

Ужасно много красивых слов. К сожалению, они не относятся к рассматриваемой теме. Потому, что ядру мало интересно что юзерспейс чудит, ведь а) malloc относится к юзерспейсу и б) существовуют и другие реализации malloc — в том числе пофичастей чем глибсишная. Взаимоотношения ядра и юзерспейса заканчиваются в районе brk/madvise/mmap/mlock/mprotect и родственных им функций. Список можно продолжать, но есть надежда, что тот, кто кодил на Си сумеет прочесть see also в man и раскрутить этот граф.

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


Давайте заново, а то я чувствую что вы обижаетесь. Вы проделали хорошую работу, написали статью, чтобы людям было понятнее, меньше ошибок совершали, больше разбирались в ИТ. Вы — молодец, и я ни в коем случае не хотел обесценить ваш труд. Вопрос управления памятью в линуксе ни разу не тривиален, и время от времени всплывают научные публикации на эту тему: https://opus4.kobv.de/opus4-fau/frontdoor/index/index/docId/8340
и даже целые книги: https://repo.zenk-security.com/Forensic/The%20Art%20of%20Memory%20Forensics%20-%20Detecting%20Malware%20and%20Threats%20in%20Windows,%20Linux,%20and%20Mac%20Memory%20(2014).pdf
Тем не менее, вам правильно замечают коллеги, что эксперимент RAM+SWAP честно было бы сравнивать с RAM+RAM. И тогда все иллюзии по поводу необходимости SWAP на диске исчезнут. Тем более, что мы живём во время активного развития DCPM, когда границы RAM и дисковой подсистемы уже довольно размыты.
Я бы почитал структурированную статью о современных алгоритмах выделения памяти в зависимости от функции процесса, которому она выделяется. А то в интернете везде кусками — где-то про мьютексную аллокацию, где-то про slabinfo, где-то про iomem, а так чтобы всё вместе и без воды — нигде нет.

А какой смылс сравнивать с RAM + RAM? Если я удвою объем памяти — у меня все данные + кэш влезут в оперативку — системе даже не нужно будет искать свободную память. Вопрос в том что чтобы удвоить их, нужно вложить шестизначную сумму, а это… Несколько неадекватная сумма, скажем так — особенно если учесть, что система загоняетя в такие граничные условия нечасто — а точнее, очень редко. Если это станет систематическим кейсом — можно думать об апгрейде. Но если это происходит раз-два в квартал на пару часов — то почему бы и нет, если система сохраняет достаточную отзывчивость.

При таких вводных — разумеется, покупать оперативную память не стоит. Мне казалось, мы рассматриваем кейс с более-менее регулярным использованием swap. Даже скажем "с перманентным".

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

Именно так. Юзерспейс может делать всё что угодно на самом деле — вести собственную буферизацию, сам делать весь I/O, управлять кэшами и т.д. — но это уже его кухня и к логике работы ядерных механизмов это отношения не имеет

Но ведь у вас главная претензия была к прибитой вкладке хрома. Хром же в юзер-спейс запускается. Исходя из данных, которые от вас поступают, что со swap, что без, его бы oom-killer прибил, если в юзер-спейс место закончится, верно?

Это могла быть не вкладка хром о окно либреоффиса, окно вскода, окно терминала, дисплейный сервер. Не повезло хрому с вкладкой гуглдокса, который решил проявить активность невовремя.
а я, если честно, не понял, что хотел автор при таких граничных тестах.
Показать поведение в граничных условиях.

Поскольку если границы срабатывания механизма свапинга не достигнуты (граничные улсоивя не достигнуты) — свапинга не происходит и смотреть нечего
Но в комментариях к прошлой статье показали, что происходит.
В статье вроде почти всё понятно, но один момент я так и не понял: почему при тесте с swappiness=0 мы получаем OOM-kill, а при полном отключении swap — только тормоза?
При полном отключении свопа не доходит до ООМ. времени надо сильно много.
Потому, что swappiness=0 не отключает своп, а делает отношение для вытеснения в своп более непредсказуемым. Вот habr.com/ru/company/flant/blog/348324
В тексте даже есть отсылка к этой работе:
Я верю Крису Дауну, поскольку считаю что он отличный инженер и знает что говорит, когда объясняет что swap-файл позволяет системе лучше работать.

Вопрос "Почему Линукс использует своп-файл" не раскрыт в статье. Вся статья собственно про vm.swappiness = (0 | 1)


Давайте просто посмотрим описание vm.swappiness например тут: https://linuxhint.com/understanding_vm_swappiness/ :


[vm.swappiness] represents the percentage of the free memory before activating swap

(представляет собой процент свободной памяти перед активацией свопа).


Теперь подумаем, какой смысл имеет значение 0 или 1. Да никакого! 1% свободной памяти от 8ГБ — это 80МБ. Т.е. например ни одна вкладка браузера не откроется.


С другой стороны если у вас ССД, и достаточно памяти (у меня например 32 ГБ), то дефолтное значение 60% (свободной!) памяти для активации свопа — это тоже нонсенс. Это 18ГБ неиспользованной свободной памяти. Зря гонять трафик через ССД значит сокращать время его жизни.


Поэтому я успешно ставлю vm.swappiness=20 и спокойно живу без всяких ООМ.


А по заглавной теме статьи — есть 2 вопроса, на которые есть 2 простых ответа.


  • Зачем линукс использует swap-файл? Ответ: чтобы а) увеличить размер доступной программам памяти б) чтобы сохранять процессы при переходе в спящий режим;
  • Почему линукс использует swap-файл? Ответ: потому, что ядро линукса поддерживает.

И никаких мини программ не надо ))

Не надо читать всякие… глупости. Потому что swappiness определяет НЕ ПРОЦЕНТ ПАМЯТИ а относительную стоимость IO файловой системы относительно IO свапа.

www.kernel.org/doc/html/latest/admin-guide/sysctl/vm.html
swappiness
This control is used to define the rough relative IO cost of swapping and filesystem paging, as a value between 0 and 200


Дешевый FS paging < swappines < Дешевый swap

То есть swappines определяет не КОГДА начинается свапинг или реклейминг кэша, он определяет КАКАЯ МЕТОДИКА освобождения страниц будет чаще выбираться — будет ли чаще дропаться кэш (low swappiness) или анонимные страницы будут чаще уноситься в swap (high swappiness). И сваппинга вообще не будет ни при каком значении swappiness если не достигнут соответствующий watermark.

И отдельно идет vm.dirty_ratio при котором грязные страницы начинают флашиться на диск и превращаться в чистые.

Хахаха, в самом деле. Не догадался в доки ядра посмотреть. А ведь эта ссылка — в топе гугла…

В таком случае, смею заметить, в статье тоже "глупости":


Тест почти без swap

Выставляем vm_swappines = 1

:)

Не беспокойтесь, я делал тест с vm_swappines=1 и на разгруженной системе.

Swap used 1MB (при 20GB доступных), результат тот же самый, то есть

Preparing test …
Doing test …
Iteration 1 of 11
[1]+ Done { sleep 120; killall swapdemo; }
Terminated

Я не про тест, а про то, что


vm_swappines = 1

согласно документации не имеет никакого отношения к


почти без swap
Согласно документации, это должно привести к:
1. минимизации стоимости filesystem paging и максимизации стоимости свапинга анонимных страниц
2. с последующим выбором реклейминга чистых страниц кэша как метода получения свободных страниц
3. минимизации использования свапинга анонимных страниц для получения свободных страниц
4. минимизации использования свап-файла куда попадают анонимные страницы при вытесенении
Поэтому «почти без swap» это вполне корректное описание тестового сценария.

А можно ссылки на п.2,3,4? В доках по ссылке вижу только п.1., никаких специальных действий для vm_swappines = 1 там также не упомянуто. Гугл, к сожалению, тоже не помощник.


Вообще, я уверен, что этот параметр раньше был документирован по-другому. Никогда не слышал про всякие там filesystem paging и тп раньше, а этот параметр использую уже 10 лет как. Например тут (тоже кернел.орг, отметим) просто совсем другой текст. Вот какой-то такой текст я и помню.


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

Если вы не хотите, чтобы система использовала свап — добавьте ей памяти но не отключайте свап. Отключение свапа на пороговых уровнях сделает ситуацию значительно хуже, чем она была бы, если бы система немного отсвапилась.
Больно не бейте, но я таки продублирую вопрос из прошлой статьи, который вы проигнорировали.
Давайте сначала. Физически выделить больше чем RAM + SWAP нельзя, верно?
Теперь я хочу понять, утверждаете ли вы, что если я докуплю RAM размером со SWAP и выключу последний, система станет хуже работать?
Возможно, я глупый, и это должно быть как-то понятно из статьи, но мне не понятно.
Она станет работать лучше но хуже чем могла бы если бы вы просто докупили памяти но не отключали swap.
Вот второе утверждение, совершенно неочевидно и, имхо, в статье не раскрывается.
У вас есть условия «M RAM + N SWAP» и «M RAM + no SWAP». Хотелось бы добавить "(N+M) RAM + no SWAP". На той же нагрузке, разумеется.
Вот второе утверждение, совершенно неочевидно и, имхо, в статье не раскрывается.

Потому, что не факт, что той памяти, которую вы добавили, будет достаточно, даже если вы добавить столько памяти, сколько использовано свапа. То есть если у вас 8GB физическая, 8GB свап и из них 6GB использовано, то добавление 8GB практически гарантированно недостаточно. Просто потому, что 6GB у вас отсвапленых анонимных страниц — но сколько у вас зареклеймилось страниц кэша одновременно со свапингом? 1GB? 3GB?

Но конечно увеличение памяти в четыре раза — да, оно практически гарантированно избавляет от проблем за исключением очень-очень редких случаев.
В смысле? До этого же суммы памяти и свопа было достаточно.
То есть если у вас 8GB физическая, 8GB свап и из них 6GB использовано, то добавление 8GB практически гарантированно недостаточно.
Ммм… тогда почему 8Гб свопа достаточно а 8Гб ram — нет?
Потому что swap это один из двух способов восполнения свободных страниц. И если вы видите что свап существенно заполнен (один способ активно используется), то с достаточно высокой вероятностью и второй способ активно используется — просто вы его не видите.

И может случиться, что если у вас «не хватает» условно 9GB то в свапе вы например увидите 6GB а 3GB будут возмещены реклеймингом кэша.

И тогда, если вы добавите 8GB, то у вас все равно не хватит 1GB и они будут возмещаться из свапа и кэша — и 400MB пойдут из кэша а 600MB улетят в свап.

Но это всё надо смотреть на конкретно взятых системах, чтобы понимать, с какого раздела идет подъем данных — из свапа или с файловой системы.
Ладно, давайте перефразирую. Чем обычная загрузка «чистых страниц» с диска хуже подкачки чего-то из свопа?

Или лучше так. Давайте рассомтрим еще ситуацию. Будет ли система из примера выше работать лучше, если увеличить своп?
чем обычная загрузка «чистых страниц» с диска хуже подкачки чего-то из свопа?

Если реклейминг кэша это «осознанное» рещение ядра, а не вынужденное решение — то ничем не хуже (осознанное — значит что ядро имело возможность выбрать что сделать — скинуть неиспользуемую память или скинуть кэши). Вот тогда такое решение может быть ничем не хуже или даже лучше, ибо у ФС например есть прелоад. Проблема в том, что чтобы это решение было осознанным, нельзя отбирать у ядра возможности оптимизации.

Как в примере. На каждой итерации 3 гигабайта «код» + 3 гигабайта активно используемых данных. Неиспользуемые данные можно отсвапить без фатального падения для производительности системы и отдать их под необходимый код — что и происходит в успешном тесте. Но можно отобрать у системы возможности оптимизации — хоть отключив свап, хоть установив в 0/1 vm_swappiness и получить «тыкву». «Зато не свапится». Правда и не работает.
Будет ли система из примера выше работать лучше, если увеличить своп?

Если просто «увеличить своп» — в текущем описании «нет». Если свап использовался бы полностью — однозначно «да». И даже если свап «сейчас» на оптане — нет. Но если на оптане и поднять сваппинес — то скорее да. А если на HDD и поднять сваппинесс — то скорее нет. Какой ответ вас устроит? Можно долго продолжать.
Поняете «осознанности» действий ядра вы как-то можете раскрыть? Я почему-то считал, что подгрузка из свопа всегда вынужденная.

Также, с ваших же слов получается, что в реальности важна не «осознанность» ядра а возможность ему разместить в памяти все нужные для текущей задачи страницы (и чистые и грязные). Если возможности нет, то своп не помогает, и именно потому увеличение свопа не улучшает ситуацию.

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

Вот открыто у меня сейчс в опере вкладок 200, наверное, лень считать, а памяти выделено системой 5 гигов вместе с кешем (20+ свободно). Если я сейчас их все прокликаю по одно, они подгрузятся, и будет у меня сожрано еще гигов 10-15. Но если я решу запустить что-то другое тяжелое, дропнуть их совершенно не представитя проблем. $killall opera; $opera займет всего несколько секунд, и я мгновенно получу минимум 10 гиговв памяти в колонке free. А то, что каждая (давно не используемая) вкладка после этого будет на пол секунды дольше подгружаться, да как-то пофиг. И совершенно пофиг, из свопа ее подгружать или из файлового кэша браузера.

Насчет осознанности ядра — это, конечно, "мощный аргумент. То-то aerospike и oracle всякие хотят полный контроль над дисками и над кэшами, чтобы достигать максимальной производительности системы...

Только не надо забывать, что все эти ораклы, db2 и прочие mssql считают себя монопольными владельцами соответствующих систем, когда в системе фактически крутится одна задача — и поэтому требования фиксированы и расчитываются по вполне себе документированным правилам.

Которые часто имеют вид «каждой сессии потребуется N мегабайт на сессионные данные, поэтому из суммарного объема вычтите X на систему, N * Y на сесии где Y количество сессий и оставшееся отдайте в БД указав конфигурационном файле вот такие параметры ....».

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

Решение же надо принимать в многозадачных системах общего назначения (где много задач список и колтчество которых заранее неизвестны, а значит и требования к ресурсам варьируются). И на этот случай для тех кто считает что сам лучше справится с управлением ресурсами есть механизмы — они могут запросить ресурсы в монопольное использование и ядро их трогать не будет. Но надо понимать что такие ресурсы исключаются из общего менеджмента.
Только не надо забывать, что все эти ораклы, db2 и прочие mssql считают себя монопольными владельцами соответствующих систем, когда в системе фактически крутится одна задача — и поэтому требования фиксированы и расчитываются по вполне себе документированным правилам.

все правильно. Именно поэтому при прочих равных правильно 1 ВМ выделять под одну роль, а не пытаться сделать сервер-звездочку, который делает 100500 делов одновременно

Поняете «осознанности» действий ядра вы как-то можете раскрыть?

У ядра была возможность выбора из двух групп страниц, и сброс кэша был выбран потому, что кэш не используется — а значит непродуктивно занимает место и его можно отдать кому надо. Вплоть до «сбросить кэш и отдать под кэш». Но если пользователь запретил свапинг или объем свап-файла мал — и одновременно с этим у него есть приложение которое заранее запросило себе большой объем памяти, заполнило данными но не использует — тогда сброс кэша это вынужденное решение.
Я почему-то считал, что подгрузка из свопа всегда вынужденная.

В идеальном мире управление памятью не нужно и ее всегда достаточно и под кэш и под данные. В реальном мире память ограничена и иногда надо выбирать чем пожертвовать (в смысле что выкинуть из памяти). И чем больше множество вариантов выбора — тем эффективней можно сделать выбор. Ядро не сбрасывает кэши и не свапит если есть свободная память. Оно делает это только если свободной памяти нет или её недостаточно для обеспечения стабильной работы.
Но если пользователь запретил свапинг или объем свап-файла мал — и одновременно с этим у него есть приложение которое заранее запросило себе большой объем памяти, заполнило данными но не использует — тогда сброс кэша это вынужденное решение.
Так мы все ранво упремся в OOM и IO, когда оно вдруг решит ими воспользоваться. То есть, памяти заведомо меньше. чем нужно для решения задач.

Претензия в том, что если в ваших примерах, на которых основана статья, заменить своп на память вместо просто отключения, ничего такого из описываемого вами не возникнет.
Претензия в том, что если в ваших примерах, на которых основана статья, заменить своп на память вместо просто отключения, ничего такого из описываемого вами не возникнет.

опять же не поможет — из-за оптимистичного выделения памяти. Прям linux ate my RAM… Получается, надо какой-то memory boxing сделать.
И опять же — я очень хотел бы разделить кейсы "сервер" (потребление памяти фикс или по крайней мере по понятным паттернам) и "рабочая станция" (высокая конкуренция за память, многозадачный режим).

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

А сейчас вы ведете себя как пациент, который читает рекомендации врача и говорит «Доктор, зачем вы мне написали всякую фигню — я же могу просто выздороветь и тогда не надо никаких ограничений».
Но вы так подаете свою позицию, как будто бы пограничные состояния это норма жизни. На практике же, я вполне могу иметь столько памяти что они будут наблюдаться 10 минут в год. И тогда отсутствие свопа перевешивает потенциальные плюсы от него.
Еще раз, для особо упорных — ни свапинга ни вытеснения из кэша не случается если достаточно памяти. Они случаются когда памяти становится недостаточно — поэтому свап не ухудшит ситуацию своим наличием.

Свап это единственное место куда система может скинуть неиспользуемые анонимные страницы. У вас есть например /run с его контентом, /tmp куда какая-нибудь утилита распакует и забудет удалить архив. Много вариантов. Но все они сводятся к одному и тому же — без свапа анонимные страницы с неиспользуемыми данными остаются в памяти.

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

Есть набор исключений, но они из серии «как прострелить себе голову еще более неадекватным способом» типа «а не сделать ли мне свап на HDD»
Ну так еще раз, для особо упорных — если памяти достаточно, то своп не нужен. Верно?
Если говорить о Вас конкретно — то вашем случае я бы вооще рекомендовал перенести рутовую ФС в initramfs а домашний каталог держать в tmpfs.
Потому, что не факт, что той памяти, которую вы добавили, будет достаточно, даже если вы добавить столько памяти, сколько использовано свапа.

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


То есть если у вас 8GB физическая, 8GB свап и из них 6GB использовано, то добавление 8GB практически гарантированно недостаточно.

Если система нормально (без OOM) работала в сочетании 8G RAM + 8G swap — то она будет работать и в случае 16G RAM + 0 swap, причём гораздо шустрее.


То есть если вы прогоняете свой тестовый сценарий на системе 8+8 и он занимает 10 минут, то в случае с 16+0 он точно займет не больше 10 минут, но скорее всего меньше — потому что в первом случае был вовлечен ввод-вывод в своп который просто скорее всего на порядки (но минимум в разы) медленней памяти.

Никогда не отключал свап, но вижу тут человек основательно подходит, какой объем в процентах рекомендуете от объема оперативки?
Зависит от нагрузки и от диска на котором лежит swap. Для себя я установил правило «один размер RAM но не менее 8GB» для десктопов и ноутбуков, для серверов — сильно зависит от нагрузки, но там «размер RAM» это часто неадекватно много по сравнению со скоростью устройства. Кое-где (в специфических случаях) доходило до 128GB и даже 256GB.

Я на ноутбуке отдал все эти замороки на откуп sysytemd-swap. Например на данный момент у меня, при 85% занятой памяти, занято два 512mb раздела в zram(по одному на каждое ядро процессора) и два динамических, файловых чанка на диске, тоже по 512mb. Разумеется vm.* параметры ядра тоже надо потюнить по вкусу. У меня так:
cat /etc/sysctl.d/10-vm.conf


vm.swappiness = 5
vm.vfs_cache_pressure = 50
vm.dirty_ratio = 3
vm.watermark_boost_factor = 15000
vm.watermark_scale_factor = 100

Каких-то фризов, на 6 гигах памяти не замечено.

Ну без проблем. Запустите андроид студию и андроид эмулятор с оперативкой на пару гигабайт и к ним какую-нибудь идею с питоновским проектом или vscode, желательно поставленные через всякие контейнероподобные извращения.

Ну или вы просто не замечаете, потому, что не с чем сравнивать.

Нет. Есть с чем сравнивать. С тем что было из коробки, а было плохо. Лампочка HDD не переставала мигать, а в htop занятость по IO wait доходила до 90%, про LA вообще лучше не спрашивать, было грустно.

На винде бы как-то сделать такое.
занятость по IO wait доходила до 90%
Это еще по-божески.

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

Посто у меня на ноуте 90% IO диска это скорее нижняя планка чем «иногда поднимается до». Переключение между ide и браузером может занимать минуту. К счастью, я работаю дома 99% времени, и ноутом пользуюсь часов 10 в год.

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

Так я знаю. Это ужасно.
У меня есть ещё один вопрос про swap, хотя и не напрямую про статью. Как так получается, что после возвращения из pm-suspend-hybrid примерно половина занятой памяти — физическая, а вторая половина — в swap? (Допустим для простоты, что перед pm-suspend-hybrid использовалась почти вся физическая память и почти ничего из swap.)

Причём если, когда компьютер уже в suspend, таки отключить полностью питание, то после восстановления картина будет примерно такой же (занята примерно половина памяти и такой же объём swap). И от включения компьютера до этого момента (для определённости — момент, когда виден терминал, где я сказал pm-suspend-hybrid, и в нём появляется новое приглашение bash), проходит существенно меньше времени, чем от этого момента до момента, когда данные из swap более-менее все переходят в физическую память и подлагивание пропадает.
Тыканье пальцем в небо и мои догадки
Моё гипотетическое объяснение такое: Перед уходом в suspend-hybrid linux отпарвляет данные в swap в два этапа, примерно по половине объёма физической памяти за этап. Причём на первом этапе linux не оставляет копию того, что он отправил в swap, в RAM, а на втором оставляет (suspend-hybrid же).

После отключения питания, включения его обратно и загрузки ядра, linux, как бы выходя из гибернации, читает из swap подряд то, что было записано на втором этапе выше, и рассовывает страницы по физической памяти в том порядке, в котором он считал их с диска. При этом данные с диска читаются последовательно, и это быстро. На этом работа команды pm-suspend-hybrid завершается. А ядро начинает вытаскивать из swap те данные, которые туда отправлены на первом этапе, причём в том порядке, в котором их запрашивают работающие процессы. Имеем (медленное) произвольное чтение с диска.

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

Вам же еще в прошлой статье написали о том, что никому не интересно, насколько плохо работает система с недостатком памяти без свапа или со свапом.
Консенсус в том, что работает отвратительно. Да, со свапом чуть лучше. Но все равно отвратительно.


Вы в тестах сравнили систему с 16 ГБ и 32 ГБ памяти. В том тесте, где вы отключаете свап, надо было добавить 16 ГБ памяти, чтобы стало одинаково. А в текущих условиях, в чем смысл этих тестов?
Точно так же можно к системе с гигабайтом памяти добавить терабайт свапа и выделить его, показав что вкладки в хроме не упали. Но зачем?

Всё затем, что у свапа два назначения:
1. сгладить пиковые нагрузки не дав системе упасть.
2. частично скомпенсировать проблемы [возможно] неоптимально написанного ПО, которое не освобождает память когда заканчивает его использовать. Например, какой-нибудь браузер который удерживает в памяти несколько исторических страниц, которыми вы вряд ли воспользуетесь, но место они занимают. Историю для отмены по Ctrl+Z. Если всё оно лежит в анонимных страницах и не используется, то может быть безопасно выгружено.
2. лучше дропнуть такое ПО чем свопить систему.
2. Я вот совсем не против иметь редактор, который хранит в swap 9000 операций для ctrl+z. В 99% времени это не нужно, но и не мешает, а в оставшемся 1%, если ситуация такая, что понадобилось всё отменить, то уж тормоза из-за чтения swap можно потерпеть.
Пусть в файле локально хранит. Заодно сохранится история при потере питания.

Ну и эот ваш режактор не соответствует примеру выше. Там же явно написано
ПО, которое не освобождает память когда заканчивает его использовать
Ваш же обстрактный редактор не заканчивает.
Он его «может» использовать — но скорей всего до этого не дойдет. «Может понадобится если пользователь нажмет Ctrl+Z». Но скорее всего нет. А разработчики решили «не насиловать диск на каждый чих». И вот теперь у вас пять копий документа за пять последних шагов, бесцельно жрут память. А вы переключились в браузер и на хабре в камменты пишете и в четырнадцати вкладках обои в 4K открыли через «открыть в новой вкладке». А потом снова в редактор переключились и продолжили создавать нетленку. Разумное решение системы — 4K пиксмапы в свап, ресурсы редактору — чтобы вам лучше нетленилось. Ну если вы свап не отключили.
И вот теперь у вас пять копий документа за пять последних шагов, бесцельно жрут память.

а потом у меня кончилось электропитание и предыдущая ревизия отправилась в Лету… Ну-ну...

У диска есть свой контроллер и буфер чтобы писать данные без насилия.
Разумное решение системы — 4K пиксмапы в свап, ресурсы редактору — чтобы вам лучше нетленилось.
Разумное решение это файловый кэш браузера. Нетрудно убедиться, что разработчики со мной согласны — заходим в ~/.cache/opera/Cache/xxxxx

Система уже по своему желанию может дублировать его в памяти или нет. Кстати, поправьте меня, если не прав, но ведь кэш браузера почти полностью чистые страницы, и дропнуть его не представляется проблемой, верно?
И вот теперь у вас пять копий документа за пять последних шагов
Храните дельту.
  1. лучше дропнуть такое ПО чем свопить систему.

проголосуем рублем и ногами!

Docker? ;-)

systemd-containerd?

Такого нет. Есть systemd-nspawn.

Так в чем смысл сравнения систем с 16 и 32 ГБ памяти?

не рекомендую писать статью впопыхах


  1. не рассмотрено влияние других параметров (типа того же overcommit)
  2. наверное, есть разница между сервером и рабочей станцией — мы все-таки какой сценарий рассматриваем?
  3. для меня было открытием узнать, что ООМ умеет убивать любые процессы (не только те, которые пытаются сожрать память, но и другие) — но это тюнится, и убивает процессы в случае наличия кучи свободной ОЗУ (но это вообще дичь, но коллеги напарывались)

Короче — статья какая-то однобокая, ждем еще продолжения

overcommit и не рассматривал описывать — это инструмент скорее ближе к ulimit и cgroups resource management по назначению

с точки зрения того, рабочая станция или сервер разницы нет. Механизмы там одни и те же. Если вы знаете как работает механизм выделения памяти, то проанализировав ВАШУ нагрузку и собранную ВАМИ статистику вы сможете понять какие механизмы для вас более предпочтительны. И вообще сможете понять какая статистика вам нужна чтобы принять решение. А если вы не знаете и действуете по инструкции «как настроить vm.swappiness в линуксе на сервере убунту» и слепо вводите команды, то с вероятностью 70% сделаете только хуже. Поэтому сначала багаж знаний и на основании этого багажа оценивать чужие советы и принимаем решения.

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

Рассказывать про тюнинг ООМ также нет никакого желание и на самом деле никакого смысла. Если OOM пришел — это авария, финита, конец, финиш, приехали, всё — называйте как хотите. Вы не можете предсказать картину когда ООМ сработает. Защитили вы от ООМ ssh — а тут внезапно хлоп — ошибка/сбой и ваш SSH перестает отвечать распухает и ООМ радостно убивает всех вокруг старательно охраняя пухнущий кривой демон. Чисто для примера. Управление ресурсами, гарантирование ресурсов — да, резервирование — да. ООМ — нет.

ну, толку насиловать стюардессу — корень проблемы, мое личное мнение, в том, что никакое приложение не пытается понять — сколько реально памяти в системе. Толку мне от 16ГБ + своп, если у меня рабочий объем данных 32ГБ (и он все равно не влезет в ОЗУ)!? Вместо того, чтобы мне попросту не дать выстрелить себе в ногу — что делает линукс? Абсолютно верно — позволяет пострелять по ногам, как обычно.


Если OOM пришел — это авария, финита, конец, финиш, приехали, всё — называйте как хотите.

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


$ time ./swapdemo
Preparing test…
Killed

вот здесь — кто замочил приложение, по-Вашему?

Вместо того, чтобы мне попросту не дать выстрелить себе в ногу — что делает линукс? Абсолютно верно — позволяет пострелять по ногам, как обычно.

Уже раз тридцать было сказано — если вы хотите гарантировать выделение памяти — cgroups, ulimit, overcommit. Все эти инструменты вам даны — но вы вместо того чтобы ими пользоваться пытаетесь изобрести искуственный псевдоинтеллект который должен делать хорошо (но получится как всегда — «вроде бы работает»).

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


Но что непонятно. Почему выгрузка из загрузка кэша тормозит, а выгрузка и загрузка в свап тормозит меньше?

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

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

всегда => при недостатке памяти
Выгрузка кэша или сброс в свап и так возникают только при недостатке памяти.
Я это и сказал.
Разница в том, что со свопом будет выгружаться то, что дольше не использовалось.

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

Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Истории