Такий погляд може бути дуже оманливим у ряді реальних справ.
Ядро тепер забезпечує оцінку наявної пам'яті в MemAvailable
полі. Ця величина значно відрізняється від MemFree + Cached
.
/ proc / meminfo: забезпечити приблизну доступну пам'ять [опис зміни ядра, 2014]
Багато програм для балансування навантаження та розміщення робочого навантаження перевіряють / proc / meminfo, щоб оцінити, скільки вільної пам'яті доступно. Вони, як правило, роблять це, додаючи "вільний" і "кешований", що було чудово десять років тому, але напевно гарантовано помиляється сьогодні.
Це неправильно, тому що кешування містить пам'ять, яка не є вільною як кеш сторінок, наприклад сегменти спільної пам'яті, tmpfs та ramfs, і вона не включає в себе відновлювальну пам'ять, яка може займати значну частину системної пам'яті в більшості непрацюючих систем з багато файлів.
Наразі обсяг пам’яті, який доступний для нового робочого навантаження, не підштовхуючи систему до підкачки, можна оцінити з MemFree, Active (файл), неактивний (файл) та SReclaimable, а також з «низькими» водяними знаками з / proc / zoneinfo. Однак це може змінитися в майбутньому, і не слід очікувати, що користувальницький простір знатиме внутрішню частину ядра, щоб придумати оцінку кількості вільної пам'яті. Зручніше надати таку оцінку в / proc / meminfo. Якщо в майбутньому все зміниться, нам доведеться змінити це лише в одному місці.
...
Документація / файлові системи / proc.txt:
...
MemAvailable: Оцінка кількості пам’яті доступно для запуску нових програм, не змінюючи місцями. Розраховується від MemFree, SReclaimable, розміру списку файлів LRU та низьких водних знаків у кожній зоні. Оцінка враховує, що системі потрібен певний кеш сторінок, щоб добре функціонувати, і що не всі відновлювані плити будуть відновлювані, завдяки предметам, які використовуються. Вплив цих факторів буде залежати від системи до системи.
1. Інформація про доступність пам’яті
Як сказано вище, 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
як "використана" пам'ять. Я створив кілька файлів розміром 1 Гб в tmpfs. Кожне збільшення на 1 ГБ Shmem
зменшується MemAvailable
на 1 ГБ. Таким чином, розмір "списків файлів LRU" не включає загальну пам'ять або будь-яку іншу пам'ять, яку можна замінити. (Я помітив, що ці самі кількість сторінок також використовуються в коді, який обчислює "брудний межа" ).
Цей MemAvailable
розрахунок також передбачає, що ви хочете зберегти принаймні достатній кеш файлу, щоб дорівнювати "низькому водному знаку" ядра. Або половина поточного кешу - залежно від того, що менше. (Це те ж саме припущення є і для рекультиваційних плит). "Низький водяний знак" ядра може бути налаштований, але це зазвичай близько 2% системної оперативної пам'яті . Тож якщо ви хочете лише орієнтовну оцінку, ви можете проігнорувати цю частину :-).
Коли у вас працює firefox
близько 100 Мб програмного коду, відображеного в кеш-пам'яті сторінки, ви, як правило, хочете зберегти ці 100 МБ в ОЗУ :-) В іншому випадку, у кращому випадку у вас виникнуть затримки, в гіршому випадку система витратить весь свій час, обмітаючи між різними програмами. Таким чином MemAvailable
, допускається невеликий відсоток оперативної пам’яті для цього. Це може не допустити достатньо, або може бути надмірно щедрим. "Вплив цих факторів змінюватиметься від системи до системи".
Для багатьох робочих навантажень ПК пункт про "багато файлів" може не бути актуальним. Незважаючи на це, на даний момент у мене на ноутбуці є відновлювана платівка на 500 Мб (з 8 ГБ оперативної пам’яті). Це пов’язано з ext4_inode_cache
(понад 300 К об’єктів). Це сталося тому, що мені нещодавно довелося сканувати всю файлову систему, щоб знайти те, що використовує мій диск :-). Я використав цю команду df -x / | sort -n
, але, наприклад, аналізатор використання диска Gnome зробив би те саме.
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 сказано, що потрапляння меж пам'яті не викликає повернення жодної платівкової пам'яті. (У документі також є відмова від відповідальності, що він "безнадійно застарів", і що ви повинні перевірити поточний вихідний код).
cgroup-v2 відрізняється. Я думаю, що коренева група вищого рівня не підтримує облік пам'яті. cgroup-v2 все ще має memory.stat
файл. Усі поля складаються з дочірніх груп, тому вам не потрібно шукати total_...
поля. Є file
поле, що означає те саме, що cache
робили. Прикро не бачу загального поля, як rss
всередині memory.stat
; Я думаю, вам доведеться скласти окремі поля. Існують окремі статистичні дані для відновлюваної та невідшкодувальної пам’яті плит; Я думаю, що група v2 призначена для повернення плит, коли вона починає обмежуватися.
Linux-групи не автоматично віртуалізуються /proc/meminfo
(або будь-який інший файл в /proc
), так що це показало б значення для всієї машини. Це заплутало б клієнтів VPS. Однак можна використовувати простори імен, щоб замінити /proc/meminfo
файл, підроблений конкретним контейнерним програмним забезпеченням . Наскільки корисні підроблені значення, залежатиме від того, що робить це конкретне програмне забезпечення.
systemd
вважає, що cgroup-v1 не можна надійно делегувати, наприклад, контейнерам. Я заглянув всередину systemd-nspawn
контейнера моєї системи cgroup-v1. Я бачу групу, яку вона розмістила всередині, і облік пам'яті. З іншого боку, що міститься systemd
не створює звичайних груп послуг для обліку ресурсів. Якщо облік пам'яті не було включено всередині цієї групи, я припускаю, що контейнер не зміг би його включити.
Я припускаю, що якщо ви знаходитесь у контейнері cgroup-v2, він буде виглядати інакше, ніж корінь реальної системи cgroup-v2, і ви зможете побачити облік пам’яті для його групи верхнього рівня. Або якщо в групі, яку ви бачите, не ввімкнено облік пам'яті, сподіваємось, вам буде надано дозвіл, щоб ви могли ввімкнути облік пам’яті вsystemd
(або еквівалент).
MemAvailable
, це було додано в 3.14.