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

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

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

Документация FreeBSD говорит нам, что немедленному освобождению допускается только cache страницы, а не inactive.

Active,Inactive,Cache,Free — грубо говоря, это 4 пула страниц, осортированные по частоте использования. OS перемещает страницы из пула в пул в зависимости от того, насколько активно они используются.
Пул Free поддерживается ненулевым, чтобы во время срочного выделения страницы (например, во время прерывания) не возникло отказа или паузы.
Cache страницы имеют дисковое отображение — это либо копия страницы из файла, либо имеет копию в свопе — в обоих случаях её можно немедленно освободить, а если понадобится — прочитаем с диска.
Active и Inactive соотв — часто (активно) и нечасто используемые страницы. Они могут как иметь дисковое отображение, так могут и не иметь (в этом случае при нехватке памяти они вытесняются в своп)
К сожалению и это не отвечает на вопрос «сколько в данный момент может быть доступно памяти приложению?»

# top -b 0 | grep Mem
Mem: 1925M Active, 53G Inact, 2901M Wired, 431M Cache, 3310M Buf, 4267M Free

Выделяю 100M блоками пока не произойдёт исключение и освобождаю.
# top -b 0 | grep Mem
Mem: 1832M Active, 1398M Inact, 3091M Wired, 431M Cache, 1949M Buf, 56G Free

В итоге Cache вообще остался нетронут, Inact похудел на 52G. Но как выяснить, что эти 52G были доступны?
Хорошая статья, но… Эм…
Шапокляк меня немного напрягает…
Мне кажется, это проблема tmpfs.
Я бы рекомендовал попробовать повторить эксперимент, но вместо tmpfs написать программу, которая захавает память и останется работать.

При этом непонятно почему остался Swap: 2502M Used
По личному опыту (и смутной памяти документации), счетчик used у свопа работает по принципу «только прибавляем».
Т.е. swap used показывает, на сколько своп был заюзан вообще с момента примонтирования свопа.
Отчасти на это намекает «used», а не «in use».
Причем, как в linux, так и во freebsd.
счетчик used у свопа работает по принципу «только прибавляем».

[19:32]# swapinfo
Device 1K-blocks Used Avail Capacity
/dev/ada0b 5022720 311000 4711720 6%
[21:30]# swapinfo
Device 1K-blocks Used Avail Capacity
/dev/ada0b 5022720 309288 4713432 6%
т.е. работает и на освобожение.
Другой вопрос зачем он вообще используется при 13G Free (и с момента старта системы Free ниже 12 не опускалась).
Mem: 20M Active, 244M Inact, 2206M Wired, 10M Cache, 1643M Buf, 13G Free
Swap: 4905M Total, 303M Used, 4602M Free, 6% Inuse

Но вопрос свопа второстепенен.

Мне кажется, это проблема tmpfs.

Нет, проблемы проявляются и без него. Я задействовал tmpfs просто для наглядности.
Во-первых, в линуксе есть vm.swappiness, указывающий степень свопливости линукса — выше величина, сильнее упреждающий своппинг. 0 отключает.

Во-вторых, подсчёт свободной памяти на linux'е — катастрофа. Предсказать, когда именно придёт oom почти невозможно, ибо free уже нет давно, а какую часть cached/buffers можно выкинуть даже само ядро толком не знает (tmpfs жрёт buffers, но выкинуть из памяти нельзя).

Видимо, у freebsd с этим не легче. Очень хочется, чтобы кто-то научился считать реальную свободную память.

А ещё очень хочется научить ограничивать paging. Потому что одному «свободная память потерянная память», а другому — просранная оперативка виртуалок, которые дважды кешируют то, что хост уже и так закешировал и отдаст им бысто.
Ну если есть какая-нибудь возможность определить какие именно файлы и когда не нужно кэшировать, то может поможет fadvise?
QEMU also supports a wide variety of caching modes. If you're using raw volumes or partitions, it is best to avoid the cache completely, which reduces data copies and bus traffic
Я бы предпочёл иметь ситуацию, когда объём кеширования управляется хостом, а не гостями. Сейчас картинка такая: у гостя 64Гб, реальных данных в памяти на гигабайт, 63 гигабайта протухшего кеша которым никто не будет пользоваться. У другого гостя два гигабайта памяти и из них полтора занято данными. На выходе явная диспропорция по объёму IO с дисков (второй гость делает тяжёлое IO снова и снова). Если бы кеш был на хосте, то нагрузка была бы распределена более равномерно.
Чтобы кеш был на хосте, нужно чтобы FS была на хосте. Если хост не видет, с какого места на диске поднята страница, он не имеет права её освобождать.
Вообще FreeBSD ведет подсчет интенсивности страниц (Linux, скорее всего, тоже). В Вашем случае можно второму гостю выделить тоже 64Г, и на хосте поставить своп (лучше на SSD) на пару сот гиг. ОС определит какие страницы не используются и положит их в своп.
Ну, общепринятым является хранить образа на файловой системе хоста. Кроме специфичных случаев с SAN/общими блочными устройствами, это де-факто стандарт.

Проблема в другом: гость не видит нагрузки на хост и не может адекватно реагировать на «больше кеша, меньше кеша».
Каюсь, поспешил. Хотя хост не может непосредственно знать, какая страница в виртуалке была поднята с какого места на диске (разве что ядро гостя об этом сообщит хосту), но он может самостоятельно кешировать страницы диска. Т.е. в Вашем случае нужно ограничить память виртуалок до необходимого приложениям объема, не включая дисковый кеш, и позволить хосту заниматься кешированием диска. Не самый идеальный вариант, строго говоря (двойное кеширование, гости под прессингом нехватки памяти могут заниматься лишним свопингом..), но зато память будет более эффективно использоваться.
В современных линуксах невозможно определить «необходимый объём». Потому что придёт OOM killer и всем станет понятно, что необходимый объём был другим. Полагаться на vss нельзя (он бывает кратно больше нужного объёма), отключать оверкоммит нельзя.

Увы.
НЛО прилетело и опубликовало эту надпись здесь
Пользовательская документация, мне так кажется, не поможет в таком болезненном для ядра вопросе. Алгоритмов несколько, в Линуксе зависит еще от аллокатора, выбранного при настройке исходников ядра, несколько уровней зонирования, buddy system, slab, помимо pages на page frames, необходимо, чтобы память сильно не фрагментировалась, многое хранится в ней до самого запроса на освобождение и т.д. Лучше сразу исходники читать и комментарии непосредственно к коду ядра. Таким методом интроспекции (top и malloc) вряд ли можно даже на интуитивном уровне догадаться, что внутри происходит.
Как будто в каких-то других ОС можно адекватно понять что к чему с памятью (в той же Windows всегда занято 95% физической памяти), поэтому это не «амнезия FreeBSD», а более фундаментальная проблема. Тяжело учесть и грамотно показать все распределение памяти в современной ОС. А если сюда добавить еще shared memory (некоторые подвиды которой вы вообще нигде не увидите никакими средствами в FreeBSD (показывает только System V)), то вообще печально.

В фре пользуюсь htop, который работает через прослойку linux procfs, которая дополнительно вносит свою лепту в вычисления, но понять самое важное всегда можно. В списке процессов в колонке RES всегда значение, которому можно верить. По наблюдениям, когда сумма чисел всех процессов в RES приближается к физическому размеру памяти, начинает расти swap. Который потом уменьшается по странным законам (а иногда и не уменьшается вовсе, как вы и описали).
Менеджмент памяти ядром — это тема, скажем, примерно на 700 страниц, тут в двух словах не пересказать, не то, что «аршином измерить». Погуглите слова «linux kernel memory management pdf», если на kernel(dot)org отправит, то это то, меня, к сожалению, местные крепкие ребята лишили возможности постить ссылки (чем-то не понравилась, возможно резкостью выражений, моя приязнь к С и неприязнь к С++ в одном из тредов Интела). Не факт, что суммирование процессами занятой памяти даст адекватную картину, но это, мне кажется, ближе к теме. Ну и сама по себе задача измерить доступную память очень зыбка, даже Гугл не решается ее измерять перед компиляцией Хромиума в Генте, оценивает свободное место на диске и общее количество оперативки.
htop насверное самый не аккуратный способ посмотреть память на freebsd. Начиная от того, что ZFS ARC пропадает из всех вычислений, заканчивая что cpu load тоже верить нельзя.

У меня swap растет при «свободных» 15 гигабайтах памяти. После пары часов работы, из 32 остается «свободных» в районе 5, и только потому, что на диске занимаего простраства меньше чем оперативной памяти. Hit rate в ARC так совсем до 98%. Tmpfs руками нигде не используется. Не жалуюсь, но от нормального htop'a не отказался бы.
Зарегистрируйтесь на Хабре, чтобы оставить комментарий

Публикации

Изменить настройки темы

Истории