Эта точка зрения может вводить в заблуждение в ряде реальных случаев.
Теперь ядро предоставляет оценку доступной памяти в MemAvailable
поле. Это значение значительно отличается от MemFree + Cached
.
/ proc / meminfo: предоставить приблизительную доступную память [описание изменения ядра, 2014]
Многие программы балансировки нагрузки и размещения рабочей нагрузки проверяют / proc / meminfo, чтобы оценить объем свободной памяти. Как правило, они делают это, добавляя «free» и «cached», что было хорошо десять лет назад, но в значительной степени гарантированно ошибается сегодня.
Это неверно, потому что Cached включает в себя память, которая не является доступной в качестве кэша страниц, например сегменты разделяемой памяти, tmpfs и ramfs, и не включает в себя исправляемую память slab, которая может занимать большую часть системной памяти в большинстве простаивающих систем с много файлов.
В настоящее время объем памяти, доступной для новой рабочей нагрузки, без принудительной загрузки системы в систему, можно оценить по MemFree, Active (файл), Inactive (файл) и SReclaimable, а также по «низким» водяным знакам из / Proc / ZoneInfo. Тем не менее, это может измениться в будущем, и пользовательское пространство не должно ожидать, что оно знает внутреннее ядро, чтобы оценить объем свободной памяти. Такую оценку удобнее представить в / proc / meminfo. Если что-то изменится в будущем, мы должны изменить это только в одном месте.
...
Documentation / filesystems / proc.txt:
...
MemAvailable: оценка объема доступной памяти для запуска новых приложений без замены. Рассчитывается из MemFree, SReclaimable, размера файлов LRU списков и нижних водяных знаков в каждой зоне. Оценка учитывает, что системе необходим некоторый кэш страниц, чтобы функционировать хорошо, и что не все восстанавливаемые плиты будут пригодны для использования из-за используемых предметов. Влияние этих факторов будет варьироваться от системы к системе.
1. MemAvailable детали
Как сказано выше, tmpfs и другая Shmem
память не могут быть освобождены, только перемещены для подкачки. Cached
Это /proc/meminfo
может вводить в заблуждение из-за включения этой заменяемой Shmem
памяти. Если у вас слишком много файлов в tmpfs, это может занять много вашей памяти :-). Shmem
также может включать в себя некоторые выделения графической памяти , которые могут быть очень большими.
MemAvailable
намеренно не включает в себя заменяемую память. Слишком большой обмен может привести к длительным задержкам. Возможно, вы даже выбрали запуск без пространства подкачки или допустили только относительно ограниченное количество.
Мне пришлось перепроверить, как MemAvailable
работает. На первый взгляд в коде, похоже, не упоминается это различие.
/*
* Not all the page cache can be freed, otherwise the system will
* start swapping. Assume at least half of the page cache, or the
* low watermark worth of cache, needs to stay.
*/
pagecache = pages[LRU_ACTIVE_FILE] + pages[LRU_INACTIVE_FILE];
pagecache -= min(pagecache / 2, wmark_low);
available += pagecache;
Тем не менее, я обнаружил, что это правильно относится Shmem
к «использованной» памяти. Я создал несколько файлов 1GB в TMPFS. Каждое увеличение на 1 ГБ Shmem
уменьшается MemAvailable
на 1 ГБ. Таким образом, размер «списков файлов LRU» не включает общую память или любую другую заменяемую память. (Я заметил, что те же самые числа страниц также используются в коде, который вычисляет «грязный лимит» ).
Этот MemAvailable
расчет также предполагает, что вы хотите сохранить как минимум достаточное количество файлового кэша, чтобы соответствовать «низкому значению ядра» ядра. Или половина текущего кэша - в зависимости от того, что меньше. (Это делает то же самое предположение для исправимых плит также). «Низкий водяной знак» ядра может быть настроен, но обычно он составляет около 2% системной памяти . Так что если вам нужна только приблизительная оценка, вы можете проигнорировать эту часть :-).
Когда вы используете firefox
около 100 МБ программного кода, отображенного в кеше страницы, вы обычно хотите сохранить эти 100 МБ в ОЗУ :-). В противном случае, в лучшем случае вы будете страдать задержками, в худшем случае система будет тратить все свое время обмолота между различными приложениями. Так MemAvailable
что позволяет небольшой процент оперативной памяти для этого. Это может не позволить достаточно, или это может быть слишком щедрым. «Влияние этих факторов будет варьироваться от системы к системе».
Для многих рабочих нагрузок ПК вопрос о «большом количестве файлов» может быть неактуальным. Несмотря на это, в настоящее время у меня на ноутбуке 500 МБ памяти для восстановления (из 8 ГБ ОЗУ). Это связано с ext4_inode_cache
(более 300К объектов). Это произошло потому, что мне недавно пришлось сканировать всю файловую систему, чтобы найти то, что использовало мое дисковое пространство :-). Я использовал команду df -x / | sort -n
, но, например, Gnome Disk Usage Analyzer сделал бы то же самое.
2. [править] Память в контрольных группах
Так называемые «Linux контейнеры» построены из namespaces
, cgroups
и различных других функций по вкусу :-). Они могут предоставить достаточно убедительную среду для запуска чего-то, почти такого же, как полноценная система Linux. Хостинговые сервисы могут создавать такие контейнеры и продавать их как «виртуальные серверы» :-).
Хостинговые серверы также могут создавать «виртуальные серверы», используя функции, которых нет в основной Linux. Контейнеры OpenVZ предварительно датируют основные групповые группы на два года и могут использовать «beancounters» для ограничения памяти. Таким образом, вы не можете точно понять, как работают эти ограничения памяти, если вы только читаете документы или задаете вопросы о ядре Linux. cat /proc/user_beancounters
показывает текущее использование и ограничения. vzubc
представляет его в чуть более дружественном формате. Главная страница на beancounters документов имен строк.
Контрольные группы включают в себя возможность устанавливать ограничения памяти для процессов внутри них. Если вы запустите свое приложение внутри такой группы, то не вся системная память будет доступна для приложения :-). Итак, как мы можем увидеть доступную память в этом случае?
Интерфейс для этого отличается по-разному, в зависимости от того, используете ли вы cgroup-v1 или cgroup-v2 .
Мой ноутбук устанавливает cgroup-v1. Я могу бежать cat /sys/fs/cgroup/memory/memory.stat
. Файл показывает различные поля , включая total_rss
, total_cache
, total_shmem
. shmem, включая tmpfs, учитывает ограничения памяти. Я думаю, вы можете рассматривать total_rss
как обратный эквивалент MemFree
. И есть также файл memory.kmem.usage_in_bytes
, представляющий память ядра, включая плиты. (Я предполагаю, memory.kmem.
также включает memory.kmem.tcp.
и любые будущие расширения, хотя это явно не задокументировано). Не существует отдельных счетчиков для просмотра памяти исправимых плит. В документе для cgroup-v1 говорится, что превышение пределов памяти не приводит к восстановлению какой-либо памяти slab. (В документе также есть заявление об отказе от ответственности за то, что оно «безнадежно устарело» и что вам следует проверить текущий исходный код).
cgroup-v2 отличается. Я думаю, что корневая группа верхнего уровня не поддерживает учет памяти. У cgroup-v2 все еще есть memory.stat
файл. Все поля суммируются по дочерним cgroups, поэтому вам не нужно искать total_...
поля. Есть file
поле, что означает то же самое, что и cache
сделал. Досадно, я не вижу общее поле, как rss
внутри memory.stat
; Я полагаю, вам придется сложить отдельные поля. Есть отдельная статистика для исправляемой и невосстановимой памяти плиты; Я думаю, что v2 cgroup предназначена для восстановления плит, когда она начинает исчерпывать память.
Linux cgroups автоматически не виртуализируется /proc/meminfo
(или любой другой файл в нем /proc
), поэтому будут отображаться значения для всей машины. Это может запутать клиентов VPS. Однако можно использовать пространства имен для замены /proc/meminfo
файлом, подделанным конкретным программным обеспечением контейнера . Насколько полезны поддельные значения, будет зависеть от того, что делает это конкретное программное обеспечение.
systemd
считает, что cgroup-v1 нельзя безопасно делегировать, например, контейнерам. Я заглянул внутрь systemd-nspawn
контейнера в моей системе cgroup-v1. Я вижу группу, в которую она была помещена, и память об этом. С другой стороны, содержимое systemd
не устанавливает обычные c-группы для службы для учета ресурсов. Если учет памяти не был включен внутри этой группы, я предполагаю, что контейнер не сможет включить его.
Я предполагаю, что если вы находитесь внутри контейнера cgroup-v2, он будет отличаться от корня реальной системы cgroup-v2, и вы сможете увидеть память, учитывающую ее cgroup верхнего уровня. Или, если вы видите, что в cgroup не включен учет памяти, возможно, вам будет делегировано разрешение, чтобы вы могли включить учет памяти вsystemd
(или эквивалентном).
MemAvailable
, это было добавлено в 3.14.