Почему Linux «съедает всю RAM» — и почему это не всегда проблема
Типичная ситуация: в мониторинге память занята «почти на 95–99%», и рука тянется перезагрузить сервер или «почистить кэш». В Linux это часто нормальное поведение: свободная память не должна простаивать, поэтому ядро активно использует RAM под дисковый кэш (page cache) и внутренние структуры (slab).
Но есть и обратная сторона: иногда рост памяти действительно опасен — например, из-за раздувания slab (dentry/inode), утечки в драйвере или проблем с сетевыми буферами. Ниже — практический разбор, как отличать «здоровое» потребление RAM от патологий и какими командами быстро получить точную картину.
Карта памяти: user space vs kernel space
Упрощённо RAM на сервере делится на две большие области:
- User space — память процессов (RSS/anon), heap/stack, mmap, shared libs.
- Kernel space — память ядра: slab-кэши объектов, таблицы, буферы, структуры файловой системы, сетевые структуры и т.д.
Page cache логически относится к кэшу файлов, но физически хранится в RAM и управляется ядром. Важный момент: при необходимости ядро обычно быстро «отдаёт» page cache под процессы. А вот часть kernel memory (включая часть slab) освобождается сложнее; если она растёт бесконтрольно и не возвращается, это уже сигнал копать глубже.

Быстрый чек: free/top и правильная интерпретация
Начать стоит с базовой сводки. На современных дистрибутивах free показывает ключевые колонки available и buff/cache:
free -h
Что смотреть в первую очередь:
- available — сколько памяти система может отдать приложениям без активного свопинга (лучший быстрый индикатор «нормально/ненормально»).
- buff/cache — суммарно файловый кэш + slab и другие кэши ядра.
Практическое правило: если
MemAvailable(илиavailableвfree) стабильно не проседает и нет OOM — «занято 99%» само по себе не диагноз.
Но free не объясняет, что именно лежит внутри buff/cache. Для детализации переходим к /proc/meminfo.
/proc/meminfo: что читать в первую очередь
/proc/meminfo — основная «правда» о распределении RAM. Снимем текущее состояние:
cat /proc/meminfo
Поля, которые почти всегда полезны при разборе:
MemTotal,MemFree,MemAvailable— базовые ориентиры по доступной памяти.Buffers,Cached— компоненты файлового кэша (в реальности важнее смотреть на картину целиком).Slab— общий объём slab (обычно примерноSReclaimable + SUnreclaim).SReclaimable— «возвратный» slab: кэш объектов, который ядро может освобождать при давлении на память.SUnreclaim— «невозвратный» slab: если он стабильно растёт — повод насторожиться.AnonPages— анонимная память процессов (heap/stack и т.п.), часто основной потребитель при росте приложений.Mapped— mmap (в том числе файловые маппинги и библиотеки).Dirty,Writeback— грязные страницы и страницы в записи (важно при проблемах с диском/ФС).SwapTotal,SwapFree,SwapCached— признаки давления по памяти и участия swap.PageTables— память на таблицы страниц (может расти при большом числе процессов/маппингов).
Как отличить page cache от slab по meminfo
Быстрая практическая логика:
- Если в основном растёт
Cachedи при этомMemAvailableостаётся адекватным — это чаще всего page cache. - Если растут
Slab/SReclaimable/SUnreclaim— это кэши объектов ядра (часто ФС/сеть/подсистемы хранения).
Уточнение: Cached не равен «строго page cache 1:1» и может включать нюансы tmpfs/ramfs и другие компоненты. Поэтому смотрим на динамику нескольких полей, а не на одну строку.
Slab и kmem_cache: что это и почему оно растёт
Slab allocator — механизм ядра для быстрого выделения памяти под множество объектов одинакового типа. Для каждого типа создаётся кэш — kmem_cache (например, для dentry, inode, сетевых структур, различных kmalloc-*).
Зачем это нужно: выделение и освобождение становятся предсказуемыми и быстрыми, снижается фрагментация. Поэтому рост slab может быть нормальным при активной работе файловой системы или сети.
Проблема начинается, когда slab растёт, а назад не возвращается (особенно SUnreclaim), и при этом MemAvailable падает, появляется свопинг или OOM.
slabtop: «топ» по slab-кэшам
Основной инструмент первичной диагностики slab — slabtop. Он показывает, какие kmem_cache занимают память и как меняется число объектов.
sudo slabtop -o
Полезные колонки (названия могут немного отличаться по версии):
- NAME — имя кэша (например:
dentry,inode_cache,kmalloc-*). - ACTIVE / NUM_OBJS — сколько объектов используется и сколько всего выделено.
- OBJ SIZE, OBJ/SLAB — размер объекта и плотность размещения.
- CACHE SIZE — оценка, сколько RAM съедает кэш.
Частые «виновники» и что они означают
На практике чаще всего всплывают такие истории:
dentry,inode_cache— кэши каталогов и inode. Растут при обходах больших деревьев (бэкапы, индексация, CI-агенты), на серверах с миллионами мелких файлов, на контейнерных хостах.kmalloc-*— универсальные кэши для разных подсистем. Если лидируют большиеkmalloc-4096,kmalloc-8192и выше — часто это сеть, драйвер, ФС или стек хранения.sock_inode_cacheи похожие — могут коррелировать с большим числом соединений/сокетов или с ситуациями, когда соединения/дескрипторы закрываются не так, как ожидалось.
Один снимок
slabtopпочти ничего не доказывает. Снимайте 2–3 замера с интервалом 5–15 минут и сравнивайте: растёт ли конкретный кэш монотонно и совпадает ли это с нагрузкой.
Page cache: почему большой Cached — это часто хорошо
Page cache — кэш файловых страниц. Для веб-сервера, PHP-приложения, статики, очередей, баз данных и любых I/O-нагрузок ядро будет стараться держать «горячие» данные в RAM, чтобы реже ходить на диск.
Признаки «здорового» page cache:
Cachedбольшой, ноMemAvailableтоже на комфортном уровне.- При запуске тяжёлых задач
Cachedуменьшается, а система не уходит в постоянный swap. - Нет событий OOM-killer, нет заметного thrashing.
Когда «кэш» может быть симптомом:
- Сильно растут
DirtyиWriteback: подсистема хранения не успевает сбрасывать данные. MemAvailableпадает, начинается свопинг, а освобождение не происходит ожидаемо: тогда дополнительно проверяем slab, закреплённые страницы (pinned memory), cgroups/лимиты контейнеров, драйверы и сетевые буферы.
Если вы отдельно оптимизируете кэширование на уровне веб-сервера, полезно сопоставлять эффекты: например, как настройки Nginx влияют на попадание в page cache. По теме можно посмотреть материал про карту кэша через map в Nginx: как управлять кэшированием и форматами через map в Nginx.

drop_caches: что делает, когда уместно и чем опасно
drop_caches — интерфейс для принудительного сброса кэшей ядра. Это не «лечение утечки», а инструмент, который временно освобождает память ценой деградации производительности (кэш придётся прогревать заново).
Перед сбросом кэша обычно синхронизируют грязные страницы на диск:
sync
Дальше варианты:
echo 1 | sudo tee /proc/sys/vm/drop_caches
Сбрасывает page cache.
echo 2 | sudo tee /proc/sys/vm/drop_caches
Сбрасывает dentry и inode кэши (часть slab, связанная с ФС).
echo 3 | sudo tee /proc/sys/vm/drop_caches
Сбрасывает и page cache, и dentry/inode.
Когда drop_caches действительно уместен
- Тесты и бенчмарки, где нужно «холодное» чтение с диска.
- Разовая аварийная мера, когда нужно быстро освободить RAM, и вы понимаете последствия (параллельно расследуя первопричину).
- После массовых файловых операций (миллионы мелких файлов), чтобы проверить, возвращается ли память и что именно было в кэше.
Когда не надо
- На проде «по расписанию» ради красивых графиков RAM.
- Чтобы «исправить kernel memory leak»: при утечке память вернётся или продолжит расти.
- Если проблема в
SUnreclaimили в закреплённой памяти: эффект будет слабым, а I/O просядет.
Kernel memory leak: как заподозрить утечку в памяти ядра
Под «kernel memory leak» на практике часто попадает любой рост «непонятной» памяти вне процессов. Самые частые наблюдаемые признаки:
- Монотонный рост
Slab, особенноSUnreclaim, без откатов. - Рост конкретных кэшей в
slabtop, который не коррелирует с реальной нагрузкой или не уменьшается после её падения.
Алгоритм первичного расследования:
- Сделайте 3–5 снимков
/proc/meminfoиslabtopс интервалом. - Определите, что растёт: page cache или slab, и какой именно
kmem_cache. - Сопоставьте с событиями: деплой, бэкап, рост числа файлов, всплеск соединений, рестарт контейнеров, обновление ядра/драйверов.
Снимки meminfo и slabtop «в одну команду»
Чтобы сравнивать динамику, удобно сохранять краткие срезы:
date; egrep 'MemTotal|MemFree|MemAvailable|Cached|Buffers|Slab|SReclaimable|SUnreclaim|Dirty|Writeback|AnonPages|PageTables|SwapTotal|SwapFree' /proc/meminfo
sudo slabtop -o --once | head -n 25
Частые практические кейсы и что делать
Кейс 1: «Cached огромный, RAM почти 100%, но всё работает»
Если MemAvailable комфортный и нет активного свопинга — это нормальный прогрев page cache. Ничего не делайте. Если нужно убедиться, что под нагрузкой память освобождается, создайте контролируемую нагрузку и посмотрите, как меняются Cached и MemAvailable.
Кейс 2: Растёт dentry/inode_cache и не падает
Чаще всего это миллионы файлов и регулярные обходы. Проверьте:
- Нет ли задач, которые рекурсивно сканируют дерево (бэкап, индексатор, сборщик мусора, поиск по файлам).
- Контейнерный хостинг: overlayfs и большие деревья слоёв часто раздувают кэши.
- Удалённые ФС (например, NFS): могут быть свои паттерны удержания метаданных.
Разовый echo 2 или echo 3 поможет понять, «возвратная» ли это история. Если кэши тут же набираются снова — причина в нагрузке/паттерне доступа к ФС, а не в «зависшей памяти».
Кейс 3: Растёт SUnreclaim, MemAvailable падает, появляются OOM
Это уже похоже на проблему. На базовом уровне действий обычно достаточно, чтобы сузить поиск:
- Посмотреть лидеров в
slabtopи их динамику. - Проверить, не коррелирует ли рост с обновлением ядра/драйверов.
- Сопоставить с сетевой нагрузкой (бурсты соединений) и файловой активностью.
Если вы подтверждаете, что история прогрессирует и воспроизводима, правильное решение обычно инженерное: исправить первопричину (обновить/откатить ядро или драйвер, поправить приложение, ограничить ресурсы), а не «лечить» регулярным drop_caches.
Мини-шпаргалка: что считать нормой, а что — тревогой
- Норма: большой
Cachedпри хорошемMemAvailable. - Норма: умеренный
SReclaimable, который растёт и падает вместе с файловой активностью. - Тревога: устойчивый рост
SUnreclaimи конкретных кэшей вslabtopбез корреляции с нагрузкой. - Тревога: падает
MemAvailable, растёт свопинг, появляются события OOM-killer. - Опасная привычка: регулярный
drop_cachesна проде ради «красивой статистики».
Вывод
Чтобы адекватно интерпретировать linux ram usage, важно отделять page cache от slab и понимать, что «занятая память» в Linux часто полезна. Начинайте с /proc/meminfo: MemAvailable, Cached, Slab, SReclaimable, SUnreclaim. Затем используйте slabtop, чтобы увидеть конкретные kmem_cache и понять, что именно растёт. А drop_caches держите как инструмент для тестов и точечных проверок, а не как постоянное «лечение».
Если после этой диагностики вы видите стабильный рост невозвратного slab или подозрение на утечку в kernel memory, фиксируйте динамику, привязывайте к событиям и переходите к разбору подсистемы, которая удерживает память. Для проектов с предсказуемой нагрузкой иногда проще и надёжнее масштабироваться по памяти и изолировать сервисы по ролям, чем воевать с последствиями: для таких задач обычно выбирают VDS с понятными лимитами и метриками на каждый сервис.


