Чи "Кешована" пам'ять де-факто безкоштовна?


11

Під час запуску cat /proc/meminfoви отримуєте ці 3 значення вгорі:

MemTotal:        6291456 kB
MemFree:         4038976 kB
Cached:          1477948 kB

Наскільки я знаю, значення "Cached" - це кешовані диски, створені системою Linux, які будуть звільнені негайно, якщо будь-якому додатку потрібно більше оперативної пам'яті, тому Linux ніколи не закінчиться пам'яттю, доки MemFree і Cached не дорівнюють нулю.

На жаль, "MemAvailable" не повідомляється / proc / meminfo, ймовірно, тому, що він працює на віртуальному сервері. (Версія ядра 4.4)

Таким чином, для всіх практичних цілей оперативна пам'ять, доступна для програм, є MemFree + Cached.

Чи правильний цей погляд?


1
Я не хочу золото забивати це закрите, але це питання актуальне, якщо не дублікат. Я здивований, що у вас немає MemAvailable, це було додано в 3.14.
Стівен Кітт

Прийнята відповідь на це запитання використовує / proc / zoneinfo, яка також недоступна для мого відвідувача
Roland Seuhs

uname -a: Хост Linux 4.4.0-042stab134.8 # 1 SMP Пт 7 грудня 17:16:09 MSK 2018 x86_64 x86_64 x86_64 GNU / Linux
Roland Seuhs

Я підозрюю, що це система OpenVZ з ядром, яка реально базується на 2.6.32, а не на 4.4.
Стівен Кітт

1
@sourcejedi, і він був складений точно в той самий час, що і ядро ​​4.4!
Стівен Кітт

Відповіді:


10

Такий погляд може бути дуже оманливим у ряді реальних справ.

Ядро тепер забезпечує оцінку наявної пам'яті в 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 (або еквівалент).



1
це натискання нао. Я використовую посилання GitHub, оскільки вони показують перший реліз, що містить коміти (подібні до git describe --contains). Виявив, що це пов'язано як TL; DR через питання SU, яке виявилося просто цитуванням розділу, доданого до proc.txt. Але для цього питання опис комітету просто ідеальний IMO :-).
sourcejedi

MemAvailable, здається, не доступний на більшості віртуальних серверів ... що робити тоді?
Roland Seuhs

@RolandSeuhs, можливо, вивчить "beancounters". Див. Правки жирним шрифтом. Якщо у вас є запитання про коси, я буду вдячний, якщо ви задасте нове запитання. Ми завжди можемо посилатися на нього з цього, але деталі, ймовірно, не стосуються жодних читачів, які використовують основне ядро ​​Linux.
sourcejedi
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.