Сколько памяти занято: free, /proc/meminfo и vmstat

Рейтинг: 72.2% · 10 голосов
Подробный курс по диагностике и производительности Linux для админов и DevOps: с чего начать, методология USE, логи (journalctl, dmesg), процессы, CPU, память и OOM, диск и IO (iostat), сеть (ss, tcpdump), системные вызовы и strace, ltrace, perf, флеймграфы, ftrace, eBPF и bpftrace, lsof, мониторинг. Разбор каждого инструмента с чтением вывода.
Ответить
Аватара пользователя
Dmitry_SRE
Сообщения: 47
Зарегистрирован: 11 май 2026, 05:31

Сколько памяти занято: free, /proc/meminfo и vmstat

Сообщение Dmitry_SRE »

Оглавление курса (47)
  1. С чего начать диагностику Linux: методология вместо паники
  2. Первые 60 секунд: экспресс-диагностика нагруженного сервера
  3. Методологии диагностики: USE, RED и здравый смысл
  4. Логи systemd через journalctl: где искать причину
  5. Где лежат логи Linux: /var/log, dmesg и rsyslog
  6. Источники правды: load average, /proc и /sys
  7. Процессы Linux: ps, pstree и состояния процессов
  8. Интерактивный мониторинг: top и htop
  9. Метрики процессов во времени: pidstat
  10. Приоритеты и ограничения: nice, ionice, cgroups
  11. Сигналы и зависшие процессы: kill, и что делать с D-state
  12. Загрузка CPU: user, system, iowait, steal и контекст-свитчи
  13. Диагностика CPU по ядрам: vmstat и mpstat
  14. Профилирование CPU: perf top и поиск пожирателя
  15. Частоты, троттлинг и NUMA: turbostat и numastat
  16. Память Linux: RSS, VSZ, page cache и миф о нехватке памяти
  17. Сколько памяти занято: free, /proc/meminfo и vmstat (вы здесь)
  18. Поиск утечек и пожирателей памяти: smem, pmap, smaps
  19. Swap и подкачка: swapon, swappiness, когда своп - это боль
  20. OOM killer: кто и за что убил процесс
  21. Память ядра и slab: slabtop и куда уходит RAM
  22. Подсистема ввода-вывода: путь запроса от приложения до диска
  23. Диагностика диска: iostat и чтение await, %util
  24. Кто грузит диск: iotop и атрибуция io процессам
  25. Файловые системы: df, du, иноды и куда делось место
  26. Глубокая диагностика блочного слоя: blktrace и biolatency
  27. Кеш страниц и грязные данные: dirty pages, fsync, drop_caches
  28. Сетевой стек Linux: путь пакета и где возникают задержки
  29. Сокеты и соединения: ss и netstat
  30. Захват трафика: tcpdump для диагностики сети
  31. Задержки и потери в сети: ping, mtr, диагностика латентности
  32. Сеть как источник проблем: nftables, conntrack, дропы
  33. Что такое системный вызов и зачем его трассировать
  34. strace: трассировка системных вызовов на практике
  35. strace в бою: почему программа висит, падает или тормозит
  36. ltrace: трассировка вызовов библиотек
  37. Накладные расходы трассировки и безопасные альтернативы
  38. perf: универсальный профайлер Linux
  39. Флеймграфы: визуализация профиля производительности
  40. Трассировка ядра: ftrace и trace-cmd
  41. eBPF: революция в наблюдаемости Linux
  42. Инструменты eBPF на практике: BCC и bpftrace
  43. lsof: открытые файлы, дескрипторы, кто держит файл и порт
  44. Разбор кейса: приложение тормозит - пошаговая диагностика
  45. Непрерывный мониторинг: sar, node_exporter, Grafana, Zabbix
  46. Диагностика в контейнерах: cgroups, лимиты, Docker и Kubernetes
  47. Карта инструментов и сквозной разбор инцидента производительности
Зачем этот урок и какую боль он закрывает

Заходишь на сервер, а он еле дышит. Первый рефлекс у новичка - "наверное, кончилась оперативка". Дальше паника: запускаешь top, видишь, что памяти занято почти всё, и думаешь, что нашёл виновного. В девяти случаях из десяти это ложная тревога. Linux специально съедает почти всю свободную память под кеш, и это нормально - так и должно быть. Незанятая память - это потраченные впустую деньги, ядро это понимает.

В этом уроке разберёмся, как в Linux посмотреть память по-человечески: сколько её всего, сколько занято процессами, а сколько - кешем, который отдадут по первому требованию. Это самая частая задача админа, поэтому пройдём её руками и медленно. Главное, чему научишься: не пугаться слова "used" и понимать, что такое available - единственная цифра, которой реально стоит верить, когда решаешь, хватает памяти или пора что-то делать. А в конце добавим то, чего обычно не хватает в старых гайдах: PSI - современный (и куда более честный, чем своп) индикатор нехватки памяти, ставший на 2026 стандартом де-факто.

Работать будем на любом современном Linux с systemd - команды одинаковы на Ubuntu, Debian, RHEL, Fedora. На Astra Linux и RED OS всё читается ровно так же: то же ядро Linux и те же утилиты из пакета procps-ng, никакой магии.

Изображение

free -h: как в linux узнать объём памяти за одну команду

Команда free - первое, что стоит набрать, когда нужно быстро узнать память linux. Флаг -h (human readable) переводит байты в удобные гигабайты, -m показывает в мегабайтах, а -w (wide, есть в procps-ng) разносит buffers и cache в отдельные колонки. Запускай без sudo, права не нужны.

Код: Выделить всё

$ free -h
               total        used        free      shared  buff/cache   available
Mem:            15Gi       4,2Gi       512Mi       320Mi        11Gi        10Gi
Swap:          2,0Gi          0B       2,0Gi
Разберём строку Mem по колонкам - это и есть ответ на вопрос "сколько памяти linux и сколько реально свободно":
  • total - весь объём оперативной памяти, видимый ядру. Здесь 15Gi - значит в машине стоит 16 ГБ. Разница в том, что часть откусывает прошивка/видеоядро, плюс служебные структуры ядра, зарезервированные ещё до старта (kernel reserved). Поэтому total почти никогда не равен наклейке на планке.
  • used - память, реально занятая процессами и неосвобождаемыми структурами ядра, без кеша. Формула в procps-ng: used = total - free - buffers - cache. Тут 4,2Gi. Это нагрузка, но не вся правда.
  • free - совсем не тронутая, пустая память. Кажется, что её мало (512Mi) - и это пугает новичков. Но это НЕ повод для тревоги, читай дальше.
  • shared - в основном tmpfs (например /dev/shm, /run) и память, общая для нескольких процессов. На сервере с большим /dev/shm (часто его держит PostgreSQL, Redis, контейнеры) эта цифра бывает заметной.
  • buff/cache - буферы и страничный кеш файловой системы. Тут 11Gi - огромный кусок. Это копии файлов и метаданных в памяти, чтобы не читать их с диска. Память как бы занята, но в любой момент отдаётся приложениям.
  • available - вот главная цифра. Оценка ядра: сколько памяти реально можно отдать новым программам без ухода в своп. Берётся не как "free + весь кеш", а умнее: free плюс та часть кеша и реклеймабельного slab, которую безопасно освободить, минусуются low watermarks. Поэтому available обычно меньше, чем free + buff/cache.
Запомни простое правило: низкий free - это норма, тревога - когда низкий available. В примере free всего 512Mi, но available целых 10Gi - значит с памятью всё прекрасно, ядро просто эффективно греет кеш.

Строка Swap - файл, раздел или (на современных десктоп-сборках Fedora и Ubuntu по умолчанию) сжатый zram. Если used у свопа стабильно растёт и не падает, а available у Mem ползёт к нулю - вот это уже реальный сигнал. Но сам по себе ненулевой swap used паникой не является: ядро штатно выгружает давно не используемые страницы, чтобы освободить RAM под кеш. Об этом ниже.

/proc/meminfo: подробная карта памяти

free красиво, но это лишь выжимка. Источник правды - виртуальный файл /proc/meminfo. Ядро отдаёт его в реальном времени, читаем как обычный текст:

Код: Выделить всё

$ cat /proc/meminfo
MemTotal:       16310260 kB
MemFree:          524288 kB
MemAvailable:   10485760 kB
Buffers:          204800 kB
Cached:         10250240 kB
SwapTotal:       2097152 kB
SwapFree:        2097152 kB
Dirty:             12480 kB
Writeback:             0 kB
AnonPages:       4100200 kB
Slab:             612340 kB
SReclaimable:     430120 kB
SUnreclaim:       182220 kB
Committed_AS:    8123456 kB
Значения в килобайтах. Ключевые поля для новичка:
  • MemTotal / MemFree - то же, что total и free в free, только в kB.
  • MemAvailable - тот самый available. Это поле и есть честный ответ "сколько свободно реально". Появилось в ядре 3.14 (2014), так что есть везде - не надо больше считать руками "free плюс кеш".
  • Cached - страничный кеш, копии содержимого файлов в памяти. Большой Cached - это хорошо, диск меньше дёргается.
  • Buffers - кеш блочных операций и метаданных. Обычно небольшой.
  • AnonPages - анонимная память: куча и стеки процессов, то что выделено через malloc и не привязано к файлу. Именно её при нехватке некуда деть, кроме как в своп. Растущий AnonPages при стабильном Cached - признак, что память едят приложения, а не кеш.
  • Dirty - "грязные" страницы: данные изменены в памяти, но ещё не записаны на диск. В норме десятки-сотни мегабайт. Если Dirty пухнет до гигабайтов - диск не успевает за записью, жди фризов на fsync. Связано с sysctl vm.dirty_ratio.
  • Slab - память под внутренние структуры ядра (inode-кеш, dentry-кеш и прочее). Делится на SReclaimable (можно освободить под давлением, входит в available) и SUnreclaim (нельзя). Если SUnreclaim разрос до нескольких гигабайт - это уже похоже на утечку в ядре или драйвере, копай через slabtop.
  • Committed_AS - сколько памяти процессы суммарно "забронировали" (через malloc и mmap), даже если ещё не трогали ни байта. Если Committed_AS заметно больше MemTotal - система раздала обещаний больше, чем имеет физически (overcommit). При невезении, когда все придут забирать обещанное, сработает OOM killer.
Хочешь вытащить пару строк - грепай:

Код: Выделить всё

$ grep -E 'MemTotal|MemAvailable|Dirty' /proc/meminfo
MemTotal:       16310260 kB
MemAvailable:   10485760 kB
Dirty:             12480 kB
vmstat: память в динамике и работа свопа

free и meminfo - снимок "здесь и сейчас". А если хочется видеть, как память живёт во времени, и поймать момент, когда система начинает свопить? Для этого vmstat. Запускай с интервалом в секунду; флаг -w (wide) раздвинет колонки, чтобы цифры не слипались:

Код: Выделить всё

$ vmstat -w 1 5
--procs-- -----------------------memory---------------------- ---swap-- -----io---- -system-- --------cpu--------
 r  b         swpd         free         buff        cache   si   so    bi    bo   in   cs  us  sy  id  wa  st
 1  0            0       524288       204800     10250240    0    0    12    35  220  410   3   1  95   1   0
 0  0            0       521340       204800     10252100    0    0     0     8  198  380   2   1  97   0   0
 0  0            0       519200       204812     10253400    0    0     0    16  205  395   2   1  97   0   0
Первая строка - усреднение с момента загрузки, её игнорируй и смотри со второй. Что читать новичку:
  • free / buff / cache - те же килобайты памяти, но обновляются каждую секунду. Видно, как кеш дышит.
  • si / so (swap in / swap out) - главные герои. Сколько КБ в секунду читается из свопа (si) и выгружается в своп (so). Важно: единицы тут именно КБ/с, флаг -S единицы для si/so не меняет (известная особенность vmstat). В здоровой системе тут стабильные нули. Постоянно ненулевые si и so - система активно гоняет страницы туда-сюда, это и есть нехватка памяти и частая причина тормозов.
  • wa в блоке cpu - процент времени, когда процессор простаивает в ожидании диска (I/O wait). Высокий wa вместе с ненулевыми si/so - классический memory pressure: память кончилась, всё уперлось в диск подкачки.
  • r / b - очередь процессов, готовых бежать (r), и заблокированных в непрерывном ожидании (b). Растущий b при свопе подтверждает, что упёрлись в I/O.
Нюанс 2026: на машинах со сжатым zram-свопом si/so могут быть ненулевыми, но боли при этом мало - страницы жмутся/разжимаются в RAM, без похода на диск. Поэтому в эпоху zram один лишь si/so уже не приговор; точнее судить по PSI (см. ниже) и по wa.

Память конкретного процесса

Общая картина ясна - теперь найдём, кто именно ест память. Сортируем процессы по RSS (Resident Set Size - реально занятая физическая память) через ps:

Код: Выделить всё

$ ps -eo pid,comm,rss,vsz --sort=-rss | head -5
    PID COMMAND             RSS    VSZ
   1842 mysqld          1820432 3920100
   2310 java            1204880 5621000
    980 dockerd          210640  1820300
  • RSS - сколько физической оперативной памяти процесс занимает прямо сейчас (в КБ). Честная цифра, но с оговоркой: если процесс линкуется с общими библиотеками, их память считается ему целиком, хотя делится с другими. Поэтому простая сумма RSS по всем процессам обычно больше реально занятой RAM - двойной учёт shared-страниц.
  • VSZ - виртуальный размер: всё, что процесс себе зарезервировал, включая ещё не загруженное в RAM и просто замапленное. VSZ часто огромный и пугающий - не верь ему, смотри RSS.
Хочешь честную цифру именно "уникальной" памяти процесса (без shared-двойного учёта) - смотри PSS (Proportional Set Size), где общие страницы делятся между процессами поровну:

Код: Выделить всё

$ grep -E '^Pss:' /proc/1842/smaps_rollup
Pss:             1623840 kB
Файл /proc/PID/smaps_rollup - готовая сводка, не нужно суммировать тысячи строк smaps вручную. Для базовых деталей хватит /proc/PID/status:

Код: Выделить всё

$ grep -E 'VmRSS|RssAnon|RssFile|VmSwap' /proc/1842/status
VmRSS:   1820432 kB
RssAnon: 1500200 kB
RssFile:  320232 kB
VmSwap:    51200 kB
VmRSS - всего в RAM, RssAnon - анонимная часть (куча/стек, её и выселяют в своп первой), RssFile - страницы, подкреплённые файлами. VmSwap - сколько этого процесса уже уехало в своп. Большой ненулевой VmSwap у важного сервиса (например базы) - повод задуматься о добавлении памяти или о тюнинге vm.swappiness.

PSI: честный индикатор нехватки памяти (актуально на 2026)

Главное обновление по сравнению со старыми гайдами. Раньше единственным сигналом считали своп, но с zram и быстрыми NVMe своп перестал быть надёжным маркером боли. Современный ответ - PSI (Pressure Stall Information), доступный на cgroup v2 (а это дефолт во всех актуальных дистрибутивах: Ubuntu 22.04+, Debian 12+, RHEL 9+, свежие Astra/RED OS). PSI показывает не "сколько занято", а "сколько времени задачи реально простаивали из-за нехватки памяти" - то есть прямую меру тормозов.

Код: Выделить всё

$ cat /proc/pressure/memory
some avg10=0.00 avg60=0.12 avg300=0.05 total=1820400
full avg10=0.00 avg60=0.04 avg300=0.01 total=910200
  • some - доля времени, когда хотя бы одна задача стояла в ожидании памяти.
  • full - доля времени, когда ВСЕ незадействованные задачи стояли одновременно (полный стопор, чистая потеря тактов).
  • avg10 / avg60 / avg300 - проценты за последние 10, 60 и 300 секунд.
Грубые пороги: some avg10 выше 10-20 процентов - заметное давление на память, пора реагировать. full avg10 стабильно выше нуля - уже серьёзная проблема, система буквально стоит. Именно на эти сигналы ориентируется systemd-oomd - современный демон, который проактивно убивает прожорливые cgroup-ы ДО того, как сработает классический OOM killer ядра и заморозит всю машину. Память по cgroup-у удобно смотреть напрямую в его файлах:

Код: Выделить всё

$ cat /sys/fs/cgroup/system.slice/mysql.service/memory.current
1864441856
$ cat /sys/fs/cgroup/system.slice/mysql.service/memory.pressure
some avg10=0.00 avg60=0.20 avg300=0.08 total=2210400
Это и есть правильный способ в 2026 отвечать на вопрос "кто давит на память" в мире контейнеров и systemd-юнитов.

Типичные грабли и заблуждения
  • "used почти 100 процентов - сервер умирает". Нет. Linux ВСЕГДА старается занять память под кеш. Смотри на available, а ещё лучше на PSI, а не на used и free.
  • Чистка кеша через drop_caches "для оптимизации". Команда sync; echo 3 > /proc/sys/vm/drop_caches существует, но в проде её трогать не надо: ты просто выкинешь полезный кеш, и система начнёт медленнее читать диск, пока не прогреется заново. Это диагностический инструмент, а не оптимизация.
  • Считать VSZ занятой памятью. Виртуальный размер - бронь и мапинги, а не факт. Реальное потребление - RSS, а для честного учёта shared - PSS.
  • Суммировать RSS всех процессов и пугаться. Из-за двойного учёта общих библиотек сумма завышена. Доверяй MemAvailable от ядра.
  • Игнорировать своп vs паниковать от свопа. Немного в свопе - норма. Тревога - когда своп активно читается/пишется прямо сейчас (si/so), при этом высокий wa и растёт PSI. На zram активность свопа сама по себе почти безболезненна.
Мини-лаба: повтори руками прямо сейчас
  • Выполни free -h и найди свои total, used и available. Ответь себе: сколько памяти реально свободно? Сравни used и available.
  • Сравни: grep -E 'MemTotal|MemFree|MemAvailable|Committed_AS' /proc/meminfo - сходятся ли цифры с free? Committed_AS уже больше MemTotal?
  • Запусти vmstat -w 1 5 и посмотри колонки si, so и wa. У тебя там нули? Отлично, своп спит.
  • Найди топ-3 пожирателя: ps -eo pid,comm,rss --sort=-rss | head -4, потом загляни в /proc/<PID>/status на VmRSS и VmSwap.
  • Прочитай cat /proc/pressure/memory. Какие у тебя avg10 у some и full? Если оба около нуля - давления на память нет.
Контрольные вопросы
  • Почему низкое значение free в выводе free -h - это нормально, и на какую колонку надо смотреть вместо него?
  • Чем RSS отличается от VSZ, и почему сумма RSS по всем процессам обычно завышена по сравнению с реально занятой RAM?
  • Какие две колонки vmstat сигналят о свопинге, и почему в 2026 на машине с zram одних si/so уже мало для вывода о нехватке памяти?
  • Что показывает PSI (строки some и full в /proc/pressure/memory) и какой примерно порог some avg10 считается тревожным?
Что запомнить

free -h - быстрый снимок, /proc/meminfo - полная карта, vmstat - динамика и своп, PSI - честный индикатор боли. Главная цифра при оценке памяти - available (она же MemAvailable), а не free. used высокий - не страшно; страшно, когда available у нуля, в vmstat побежали si/so при высоком wa, а PSI some/full пополз вверх. Память процесса - это RSS (и PSS для честности), а не VSZ. В мире systemd и контейнеров смотри memory.current и memory.pressure по cgroup v2. На Astra Linux и RED OS всё ровно то же самое.
👍3 ❤️4 🔥3 😄 🤔2
Аватара пользователя
jpino
Сообщения: 1
Зарегистрирован: 24 май 2026, 21:59

Re: Сколько памяти занято: free, /proc/meminfo и vmstat

Сообщение jpino »

Спасибо, наконец дошло почему top вечно показывает что памяти почти нет, а сервер живёхонек. Смотрел не на ту колонку, надо было на available. А про PSI вообще не знал, пошёл смотреть /proc/pressure/memory на своих машинах.
👍 ❤️ 🔥 😄 🤔
Аватара пользователя
kotlin2
Сообщения: 2
Зарегистрирован: 25 май 2026, 02:32

Re: Сколько памяти занято: free, /proc/meminfo и vmstat

Сообщение kotlin2 »

А подскажите, у меня free говорит available 6Gi, но в vmstat иногда мелькает so 200-300, потом снова нули. PSI some avg10 при этом 0.0. У меня zram, получается это просто ядро холодные страницы поджимает и можно забить?
👍1 ❤️ 🔥1 😄 🤔1
Ответить
← Предыдущая глава
Память Linux: RSS, VSZ, page cache и миф о нехватке памяти
Следующая глава →
Поиск утечек и пожирателей памяти: smem, pmap, smaps

Все главы курса «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Поделиться темой: ✈ Telegram VK
Похожие запросы: как понять что съедает память на сервере linux

Вернуться в «Диагностика и производительность Linux: логи, strace, perf и eBPF»

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и 1 гость