Картина пугает любого, кто впервые её видит. Сервер только что поднят, нагрузки почти нет, а монитор показывает, что свободной памяти почти не осталось - из гигабайтов оперативки свободны считанные мегабайты. Первая мысль: где-то утечка, какой-то процесс пожирает память. Начинаются поиски виновника, попытки понять, кто съел всю оперативку. На деле виновника нет, а память занята кэшем, и это не сбой, а намеренное и здоровое поведение системы.

Суть в том, что система не оставляет память простаивать. Незанятую приложениями оперативку она пускает на ускорение работы с диском - складывает туда уже прочитанные файлы, чтобы при повторном обращении не лезть на медленный накопитель. Когда приложениям понадобится память, система мгновенно освободит кэш и отдаст её. Разберём, как читать показания о памяти правильно, почему занятый кэш - это хорошо, и на какую колонку смотреть, чтобы понять реальную доступность памяти.

Команда показывает память, но привычная колонка обманчива

Состояние памяти показывает стандартная команда обзора в человекочитаемом виде. Она разбивает оперативку на несколько колонок, и в их толковании кроется источник паники.

free -h            # обзор памяти в человекочитаемом виде

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

              total   used   free   shared  buff/cache   available
Mem:           7.7G   1.2G   4.8G     102M        1.7G        6.0G

Ключевые колонки тут две: буферы и кэш, где сидит дисковый кэш, и доступно - вот на неё и надо смотреть. Колонка буферов и кэша показывает, сколько памяти отдано под ускорение работы с диском. Колонка доступного показывает, сколько памяти приложения смогут занять без обращения к подкачке, - и в это число уже включена память кэша, которую система готова освободить по требованию.

Свободная память это растраченная память

За поведением стоит простая философия, которую стоит принять однажды и навсегда: незанятая память - это растраченная память. Если оперативка не нужна приложениям прямо сейчас, разумнее пустить её в дело, ускоряя работу с диском, чем оставлять простаивать без пользы. Поэтому система стремится держать оперативку занятой как можно полнее.

Механизм прост. При первом чтении или записи файла система попутно складывает данные в неиспользуемые области памяти - в дисковый кэш. Если эти данные понадобятся снова, их прочитают прямо из памяти, минуя медленный накопитель. Наглядный пример: прочитать большой файл дважды подряд - второе чтение окажется заметно быстрее, потому что блоки файла уже в кэше памяти, и обращаться к диску повторно не нужно.

cat /proc/meminfo | grep ^Cached   # размер собственно кэша страниц

Так со временем на любой работающей системе свободная память закономерно падает почти до нуля - вся незанятая оперативка постепенно уходит под кэш прочитанных данных. Это не признак неполадки, а признак того, что система эффективно использует имеющуюся память. Сервер, у которого через час работы много свободной памяти и пустой кэш, как раз растрачивает ресурс впустую.

Система мгновенно освобождает кэш под нужды приложений

Главное опасение - что занятый кэшем гигабайт не достанется приложениям, когда им понадобится память. Опасение напрасно. Кэш - это память напрокат, которую система отдаёт обратно мгновенно, как только приложение запрашивает оперативку. Никакого ручного вмешательства не требуется.

Когда приложение просит память, а свободной мало, система автоматически уменьшает кэш и отдаёт освобождённую память приложению. Переход бесшовный: активные программы получают нужные ресурсы, а кэш просто ужимается на необходимую величину. Данные в кэше не важны для работы программ - это лишь копии того, что и так лежит на диске, поэтому их можно сбросить без потерь в любой момент.

Именно поэтому колонка доступного в обзоре памяти включает кэш в свой счёт. Она честно отвечает на вопрос, сколько памяти приложения реально смогут занять, не прибегая к подкачке, - и это сумма по-настоящему свободной памяти плюс той, что сейчас в кэше, но готова освободиться. Ориентироваться нужно именно на эту цифру, а не на колонку свободного.

Ручной сброс кэша возможен, но обычно не нужен

Кэш можно сбросить и вручную, записав определённое значение в особый системный файл управления. Это иногда делают для измерений производительности с холодным кэшем или из любопытства.

echo 1 | sudo tee /proc/sys/vm/drop_caches   # сбросить кэш страниц

Но в повседневной работе этого делать не нужно, и более того, обычно не следует. Сброс кэша не решает никакой реальной проблемы - система и так освободит его сама, когда понадобится. А пока кэш цел, он ускоряет работу с диском. Сбросив его, мы лишь заставим систему заново читать с накопителя данные, которые только что были под рукой в памяти, и ближайшее время работа пойдёт медленнее, пока кэш не наполнится снова. Ручной сброс уместен разве что для чистоты замеров, но не как способ навести порядок в памяти.

Стоит знать и историческую деталь: когда-то буферы и кэш были раздельными механизмами, но в современных ядрах они объединены в единый кэш. Поэтому колонка буферов и кэша в обзоре показывает их суммарно, и разделять их в большинстве случаев незачем.

Когда занятая память всё же сигнализирует о проблеме

Чтобы не впасть в обратную крайность, стоит очертить, когда тревога всё же оправдана. Сама по себе полная занятость памяти кэшем - норма. Но есть признаки настоящей нехватки памяти, и их надо отличать от здорового кэширования.

Главный честный индикатор - колонка доступного. Если она показывает достаточный объём, всё в порядке, сколько бы ни было в кэше. А вот если доступного мало при том, что кэш уже невелик и ужиматься почти некуда, - это уже настоящее давление на память. Второй индикатор - активность подкачки. Когда система начинает интенсивно вытеснять данные на диск в область подкачки, это сигнал реальной нехватки оперативки, а не безобидного кэширования.

vmstat 1           # следить за подкачкой в колонках si и so

Устойчивый ненулевой обмен с подкачкой в обе стороны означает, что физической памяти не хватает и система вынуждена вытеснять данные на медленный диск - вот это уже проблема, в отличие от полного кэша при здоровой доступности. Отличать эти две картины - и есть навык правильного чтения памяти.

Что складывается в понимание

Картина проста, стоит её один раз уложить. Почти полная занятость оперативной памяти на работающем сервере - норма, а не утечка. Незанятую приложениями память система пускает под дисковый кэш, ускоряя работу с накопителем, потому что свободная память - это растраченная память. Со временем свободная память закономерно падает почти до нуля, и это признак эффективности, а не сбоя.

Читать показания памяти нужно по правильной колонке: не по свободной, которая обманчиво мала, а по доступной, которая включает готовый освободиться кэш. Система отдаёт кэш приложениям мгновенно и сама, ручной сброс обычно не нужен и лишь замедляет работу на время. А настоящую нехватку памяти выдают малая доступность при ужатом кэше и активная подкачка.

Главная мысль: система не ест память, она пускает её в дело. Паника при виде занятой оперативки рождается из взгляда не на ту колонку. Стоит запомнить, что смотреть надо на доступную память, а полный кэш - это здоровье, а не болезнь, и пугающая картина почти нулевой свободной памяти перестаёт тревожить. Оперативка занята ровно потому, что система использует её с толком, и отдаст всё нужное приложениям в тот же миг, как они попросят.