Администрирование Linux-серверов

Не хватает памяти в Linux: RAM, swap, OOM Killer и подкачка

Как отличить файловый кэш от дефицита RAM, найти причину swap и OOM Killer, а затем безопасно настроить подкачку Linux.

14 минут
абстракт�ная иллюстрация распределения памяти Linux-сервера
Занятая память в Linux ещё не означает, что серверу не хватает RAM: ядро использует свободные страницы под кэш страниц, который может освободить при необходимости. Сначала проверьте MemAvailable, динамику процессов, ввод-вывод swap и сообщения ядра Linux об OOM. Настраивать подкачку, добавлять RAM или менять vm.swappiness стоит только после определения причины.

Как читать free: занятая RAM не всегда означает дефицит

Команда free показывает сводные данные из /proc/meminfo. Для первичной оценки состояния памяти ориентируйтесь прежде всего на available, а не на free: полностью свободная RAM в работающей Linux-системе обычно невелика, потому что ядро кэширует файлы и данные блочных устройств.

Показывает RAM и swap в удобных единицах. Сравните `available` с обычным уровнем для этого сервера и посмотрите, растут ли значения `used` и использование swap во времени.
free -h

Основные столбцы строки Mem в выводе free

ПолеЧто означаетКак интерпретировать
totalОбщий объём доступной системе физической RAM.Базовая ёмкость памяти; не показывает текущий дефицит.
usedПамять, которую free считает использованной. В современных версиях procps-ng она обычно вычисляется как total - available.Полезна для динамики, но сама по себе не доказывает нехватку RAM.
freeСтраницы RAM, которые сейчас не заняты ни данными процессов, ни кэшем.Низкое значение нормально: ядро старается не оставлять полезную RAM пустой.
sharedПамять, преимущественно связанная с tmpfs и разделяемыми областями.Не является отдельным резервом и не суммируется с другими полями для оценки дефицита.
buff/cacheФайловый кэш, буферы и связанные с кэшированием структуры ядра.Значительная величина часто нормальна: существенную часть таких страниц ядро может освободить под новую нагрузку.
availableОценка памяти, которую можно выделить новым приложениям без начала активной подкачки.Главный показатель для первичной проверки. Это оценка ядра, а не обещание, что любой запрос будет выполнен.

Почему формат free может отличаться

Набор полей и формулы free менялись между версиями procps-ng; старые примеры из интернета могут показывать отдельные столбцы buffers и cache либо по-другому трактовать used. Для установленной системы сверяйтесь с man free и версией утилиты, а первичные данные при необходимости смотрите в /proc/meminfo.
Показывает исходные показатели памяти ядра. Ищите как минимум `MemTotal`, `MemFree`, `MemAvailable`, `Buffers`, `Cached`, `SwapTotal` и `SwapFree`. Не приравнивайте `MemFree` к объёму, реально доступному новым процессам.
cat /proc/meminfo

Не очищайте page cache через drop_caches как штатный способ освободить память. Это не устраняет утечку или недостаток RAM, а лишь удаляет полезный кэш и может ухудшить время последующих чтений.

Почему используется swap, хотя available ещё не равен нулю

Swap — пространство для вытесненных страниц памяти, оформленное как раздел, файл или другое подходящее блочное устройство. Обычно оно размещено на диске или SSD, но некоторые системы используют в качестве swap, например, сжатое блочное устройство zram в RAM. Сам факт занятого swap не равен аварии: ядро может заранее выгрузить давно неиспользуемые анонимные страницы, сохранив RAM для файлового кэша и активной работы. После краткого пика эти страницы могут остаться в swap, пока к ним снова не обратятся.

Показывает активные области swap: имя, тип, размер, занятый объём и приоритет. Если команда недоступна, это зависит от состава util-linux в дистрибутиве.
swapon --show
Выводит пять отчётов: первая строка обычно содержит средние значения с момента загрузки, а последующие строки — показатели за секундные интервалы. В столбцах `si` и `so` ищите объём данных, прочитанных из swap и записанных в него за секунду. Устойчивые ненулевые значения `si` либо `so` в последующих строках показывают текущую активность подкачки. Ненулевой занятый объём swap при стабильно нулевых `si` и `so` обычно менее тревожен, чем постоянный обмен данными.
vmstat 1 5

Активные si и so, падение MemAvailable, задержки приложений и рост дискового ввода-вывода вместе указывают на давление памяти. Если одновременно высоки CPU, iowait или load average, не сводите проблему автоматически к RAM: порядок диагностики этих симптомов описан в статье «Процессы, CPU и нагрузка Linux: диагностика высокой загрузки».

Сначала сохраните снимок состояния памяти

Диагностика до перезапуска службы или отключения swap

Соберите наблюдения до действий, которые изменят картину проблемы. Это особенно важно при редких пиках и повторяющихся OOM.

  1. 1
    Зафиксируйте общую память и swap
    Выполните free -h, cat /proc/meminfo и swapon --show. Сохраните вывод с временем сбора: важны MemAvailable, объём занятого swap и состав активных областей подкачки.
  2. 2
    Проверьте текущий обмен страницами
    Запустите vmstat 1 5 или наблюдайте дольше в период проблемы. Первая строка обычно отражает средние значения с момента загрузки, поэтому оценивайте последующие интервальные строки. Устойчивые ненулевые значения si либо so в них означают текущий обмен со swap, а не просто исторически занятое пространство.
  3. 3
    Найдите крупнейшие процессы
    Отсортируйте процессы по RSS — физической памяти, находящейся в RAM. Сопоставьте имя, PID и владельца с ожидаемыми службами и недавними изменениями нагрузки.
  4. 4
    Проверьте журнал ядра
    Ищите OOM-сообщения до перезапуска приложений. Если событие произошло в предыдущей загрузке, используйте журнал предыдущей загрузки, если он сохранён.
  5. 5
    Сравните показатели во времени
    Один снимок редко отличает краткий пик от утечки. Сравните RSS процессов, MemAvailable, swap и время запуска задач до, во время и после симптома.
Показывает процессы с наибольшим RSS. `rss` обычно выводится в KiB, `%mem` — доля физической RAM. [PID](/baza-znaniy/glossariy/process-identifier) нужен для сопоставления процесса с журналом и службой.
ps -eo pid,ppid,user,comm,rss,%mem --sort=-rss | head -n 20
Интерактивно показывает память и процессы. Внутри `top` можно сортировать список по памяти средствами версии утилиты; конкретные клавиши и поля зависят от реализации и настроек.
top

OOM Killer: как найти событие и выбранный процесс

OOM Killer запускается, когда ядро не может удовлетворить выделение памяти в допустимых условиях. Это может происходить при почти исчерпанной RAM и swap, но также из-за правил overcommit или лимита cgroup, даже если на уровне всего хоста память ещё видна.

Ищет сообщения ядра в журнале текущей загрузки. В строках обычно важны контекст OOM, `Killed process`, PID, имя процесса и объём памяти. Для предыдущей загрузки при наличии сохранённого journal замените `-b` на `-b -1`.
journalctl -k -b | grep -Ei 'out of memory|oom-kill|killed process'

Где могут находиться OOM-сообщения

Формат сообщений OOM, их поля и место хранения зависят от версии ядра, настройки журналирования и дистрибутива. В системе с systemd journalctl обычно читает журнал systemd; на других системах или при иной конфигурации записи могут находиться в текстовом системном журнале. Подробности отбора и хранения записей — в статье «Журналы Linux: journalctl, rsyslog и logrotate».
Ищет OOM-сообщения в кольцевом буфере ядра, если доступ к нему разрешён. Буфер ограничен размером и старые записи могли быть вытеснены; журнал обычно надёжнее для расследования.
dmesg -T | grep -Ei 'out of memory|oom-kill|killed process'

При глобальном OOM ядро выбирает жертву среди подходящих процессов хоста. При OOM внутри memory cgroup жертва выбирается в пределах группы, превысившей свой лимит; свободная память вне неё не обязательно спасёт процесс. В контейнерной среде причины OOM и действующие лимиты нужно дополнительно проверять на уровне используемой платформы, а не переносить выводы с уровня хоста.

В диагностике полезны /proc/<PID>/oom_score и /proc/<PID>/oom_score_adj: первое отражает текущую оценку процесса для выбора при OOM, второе позволяет сдвигать её. Это не причина дефицита памяти и не повод менять приоритеты без понимания последствий: защищённый процесс может оставить ядру другую, более критичную жертву.

Показывает параметры overcommit. `vm.overcommit_memory` задаёт режим учёта обещаний памяти: режимы 0, 1 и 2 имеют разную семантику в документации ядра; при режиме 2 на предел commit, среди прочего, влияет `vm.overcommit_ratio` или альтернативная настройка в KiB. Это диагностический контекст OOM, а не шаблон для изменения параметров.
sysctl vm.overcommit_memory vm.overcommit_ratio

Частые причины Linux out of memory и направление проверки

СимптомВероятные причиныЧто подтвердитДействие после подтверждения
Один OOM в момент запуска тяжёлой операцииКраткий пик выделений, слишком большой пакет данных, одновременный старт задач.Время OOM совпадает с заданием; до и после пика память восстанавливается.Разнести задачи, уменьшить параллелизм, пересмотреть размер пакета или планово увеличить RAM/swap после оценки нагрузки.
RSS одного процесса постоянно растётУтечка памяти, неограниченный кэш приложения, неверные лимиты приложения.Несколько снимков ps показывают устойчивый рост одного процесса без ожидаемого снижения.Исправить конфигурацию или код, обновить приложение по его документации; как временную меру спланировать перезапуск службы.
OOM при одновременной работе множества задачИзбыточный параллелизм воркеров, запросов, сборок или заданий.Суммарный RSS множества однотипных процессов растёт вместе с числом задач.Ограничить конкурентность, очереди и размер пулов; проверить потребление после изменения.
Процесс убит, хотя хост не выглядит заполненнымЛимит memory cgroup, включая лимит службы или контейнера.В OOM-сообщении есть признаки cgroup; для процесса действует ограничение памяти.Проверить и скорректировать лимит и модель нагрузки в том слое, где он задан.
MemAvailable регулярно низок, swap активен, OOM повторяетсяРабочий набор больше доступной RAM, недостаточно физической памяти, иногда недостаточный или отсутствующий swap.Длительная активность si/so, рост задержек и повторные OOM без одного явного процесса-нарушителя.Сократить потребление, добавить RAM; swap рассматривать как часть политики, а не как гарантированную замену RAM.

Что исправлять, если не хватает памяти Linux

Исправление должно соответствовать подтверждённой причине. Перезапуск процесса может временно вернуть память, но не устраняет утечку; добавленный swap способен пережить краткий пик, но не делает дисковую подкачку эквивалентом RAM и не гарантирует отсутствие OOM.

  • Утечка или неверная конфигурация приложения. Исправьте причину, ограничьте кэш, размер очереди или потребление воркера по документации приложения. Плановый перезапуск допустим как временная мера только после фиксации симптомов и оценки простоя.
  • Слишком много параллельных задач. Ограничьте число одновременных заданий, соединений или рабочих процессов и проверьте, как изменились RSS и MemAvailable.
  • Краткие предсказуемые пики. Перенесите тяжёлые задания, разделите входные данные или добавьте ресурсы под измеренный пик.
  • Недостаток RAM для постоянной нагрузки. Увеличьте физическую память после оценки рабочего набора и возможностей платформы.
  • Нужна резервная подкачка. Добавьте или включите swap с учётом доступного хранилища, политики данных и производительности. Создание swap-файла зависит от файловой системы, версии ядра и дистрибутива; используйте официальное руководство целевой ОС, а не универсальный рецепт для всех файловых систем.

Не начинайте с restart, swapoff или drop_caches

Эти действия меняют состояние и могут уничтожить ключевые признаки проблемы. Перед ними сохраните вывод free, /proc/meminfo, vmstat, список процессов и журнал ядра. Если проблема затрагивает службу, правила безопасного restart и последующей проверки описаны в статье «systemd и systemctl: управление службами и автозагрузкой Linux».

Когда можно очистить swap и почему swapoff опасен

Под «очистить swap Linux» обычно понимают отключение области подкачки и её повторное включение. Это допустимо как контролируемая временная операция, например после устранённого разового пика, когда есть достаточный запас RAM, нет активной деградации и известны последствия для сервисов. Само по себе занятое swap-пространство не требует очистки.

swapoff может спровоцировать OOM

При swapoff ядро должно вернуть выгруженные страницы в RAM или иным образом освободить место. Если доступной памяти недостаточно, операция может завершиться ошибкой либо создать давление памяти и привести к OOM-убийствам. Не выполняйте swapoff -a на рабочем сервере без сохранённой диагностики, оценки MemAvailable, занятого swap и влияния на службы.

Временное освобождение занятого swap

Применяйте только в согласованное окно работ и только для уже существующих областей подкачки.

  1. 1
    Сохраните исходные показатели
    Запишите вывод free -h, swapon --show, vmstat 1 5, список крупнейших процессов и сообщения OOM. Убедитесь, что причина давления памяти уже исследована.
  2. 2
    Оцените запас RAM
    Сравните MemAvailable с объёмом занятого swap и оставьте запас для работающих процессов и колебаний нагрузки. Точного универсального порога нет: важны рабочий набор и критичность сервиса.
  3. 3
    Отключите конкретную область или все активные области
    Для конкретного устройства или файла используйте sudo swapoff <путь>. Команда sudo swapoff -a пытается отключить все активные области подкачки, перечисленные ядром в /proc/swaps, в том числе включённые вручную и отсутствующие в /etc/fstab. Поэтому перед её запуском особенно тщательно проверьте запас памяти и влияние на службы.
  4. 4
    Проверьте последствия и включите swap обратно при необходимости
    Снова проверьте free -h, swapon --show, журнал ядра и работоспособность нужных служб. Для возврата конкретной области используйте sudo swapon <путь>; для областей из /etc/fstab — sudo swapon -a после проверки файла.

Настройка swap Linux: включение при загрузке

Для уже созданной области swap swapon включает её до перезагрузки. Чтобы она включалась при старте, запись должна быть корректно описана в /etc/fstab; для раздела обычно используют стабильный идентификатор устройства, например UUID, а не изменяемое имя диска. Инструменты определения UUID и порядок автоматического включения swap могут зависеть от дистрибутива.

/etc/fstab
# Пример для существующего swap-раздела; UUID замените фактическим
UUID=<uuid-своп-раздела> none swap defaults 0 0

Проверьте /etc/fstab до перезагрузки

Ошибка в /etc/fstab способна повлиять на загрузку системы. Перед правкой сохраните исходный файл, убедитесь в типе и UUID целевого устройства, затем проверьте запись контролируемым включением swapon -a и выводом swapon --show.
Включает области swap, описанные в `/etc/fstab` и ещё не активные. После выполнения проверьте `swapon --show`; команда не создаёт swap и не исправляет неверную запись в `fstab`.
sudo swapon -a

vm.swappiness: временное и постоянное изменение

vm.swappiness — не переключатель «разрешить swap» и не частота подкачки. В документации ядра он задаёт относительный вес выгрузки анонимных страниц в swap по сравнению с освобождением файловых страниц из page cache. Меньшее значение не обязано ускорить сервер, а большее не исправляет дефицит памяти.

Документация современных ядер Linux описывает диапазон 0–200 и значение по умолчанию 60, однако фактическое начальное значение может быть переопределено дистрибутивом или sysctl-конфигурацией. Перед выбором значения сверяйте документацию именно используемого ядра и рабочую нагрузку; проверьте версию ядра через uname -r и действующее значение через sysctl.

Показывает действующее значение параметра. Сначала зафиксируйте его вместе с нагрузочными показателями, чтобы иметь понятный откат.
sysctl vm.swappiness

Изменение vm.swappiness с возможностью отката

Меняйте параметр только после анализа процессов, swap и OOM. Сначала применяйте изменение временно и наблюдайте именно целевую нагрузку.

  1. 1
    Зафиксируйте исходное значение и симптомы
    Выполните sysctl vm.swappiness, сохраните free -h, vmstat и показатели приложения. Определите, какую гипотезу проверяете: например, избыточную активность swap при конкретной нагрузке.
  2. 2
    Установите временное значение
    Выполните sudo sysctl -w vm.swappiness=<значение>, где <значение> находится в диапазоне, документированном для вашего ядра. Изменение действует до перезагрузки или следующего применения sysctl-конфигурации.
  3. 3
    Проверьте эффект и откат
    Повторите целевую нагрузку и сравните vmstat, MemAvailable, задержки приложения и сообщения ядра. При ухудшении верните зафиксированное исходное значение той же командой sysctl -w.
  4. 4
    Сделайте настройку постоянной только после проверки
    Добавьте отдельный файл sysctl в каталог, который читает ваш дистрибутив, например /etc/sysctl.d/99-local-memory.conf, затем примените его штатным механизмом. Порядок файлов, наличие sysctl --system и источники переопределения зависят от ОС и версии.
/etc/sysctl.d/99-local-memory.conf
# Значение выбрано и проверено для конкретной нагрузки
vm.swappiness = <значение>
Перечитывает sysctl-конфигурацию из стандартных каталогов, если такой порядок поддерживается целевой системой. Просмотрите вывод: другой файл может переопределить `vm.swappiness`. После этого повторно выполните `sysctl vm.swappiness`.
sudo sysctl --system

Что проверять после изменения

Изменение vm.swappiness обратимо, но может менять баланс между кэшем файлов и анонимной памятью. Оцените не только объём занятого swap, но и si/so, MemAvailable, задержки приложения и сообщения OOM. Если причина — утечка, лимит cgroup или недостаток RAM, настройка параметра ядра не заменяет устранение причины.

Термины в статье

Кэш страниц — управляемый ядром Linux кэш в оперативной памяти, хранящий данные файлов и блочных устройств для ускорения повторных чтений и буферизации записей.
Процесс — экземпляр выполняемой программы в Linux с PID, виртуальным адресным пространством, состоянием и связанными с ним ресурсами.
Системная служба — программный компонент, которым ОС управляет как логической единицей для фонового выполнения задач или предоставления функций программам и пользователям.
Утечка памяти — ошибка управления жизненным циклом данных, при которой выделенная память больше не нужна, но не освобождается или остаётся достижимой по лишним ссылкам.
Ядро Linux — центральный компонент ОС, управляющий аппаратными ресурсами и предоставляющий системные интерфейсы; оно не включает пользовательские утилиты и менеджер пакетов.
cgroup — механизм ядра Linux для объединения процессов в иерархические группы с раздельным учётом и управлением потреблением ресурсов.
journalctl — консольная утилита чтения и фильтрации журнала systemd, выводящая сообщения по времени, юниту, загрузке системы, приоритету и другим полям.
Load average — среднее число задач Linux, выполняющихся или готовых к выполнению на CPU либо находящихся в непрерываемом ожидании, за 1, 5 и 15 минут.
OOM Killer — механизм ядра Linux, который при критическом дефиците памяти выбирает и принудительно завершает процесс, чтобы освободить память и продолжить работу системы.
PID — числовой идентификатор экземпляра процесса, назначаемый ядром Linux для его адресации; после завершения процесса номер может быть использован повторно.
Swap — область на диске или SSD, используемая ядром Linux для размещения вытесненных страниц памяти, когда RAM требуется более активным данным.
swappiness — параметр ядра Linux, задающий относительную склонность освобождать память выгрузкой анонимных страниц в swap вместо вытеснения файлового кэша.
systemd — система инициализации и менеджер служб Linux, управляющий службами и другими ресурсами как объектами unit, обычно описанными unit-файлами.

Вопросы по теме

Все вопросы и ответы

Почему в `free` мало free, но это не дефицит памяти?

Это нормально: Linux использует незанятую RAM для файлового кэша и может освободить значительную часть этого кэша при новой нагрузке. Для первичной оценки смотрите прежде всего на available, а не на free. Поле used полезно отслеживать в динамике, но само по себе также не доказывает нехватку памяти.

Может ли OOM Killer убить процесс, если на хосте ещё есть память?

Да, это возможно. При глобальном OOM ядро выбирает жертву среди подходящих процессов хоста, когда не может удовлетворить выделение памяти в допустимых условиях. Но OOM также бывает локальным — внутри memory cgroup. В таком случае ядро выбирает процесс только в группе, которая превысила установленный лимит; свободная RAM за пределами этой группы не обязательно поможет.

Сначала проверьте сообщения ядра: journalctl -k -b | grep -Ei 'out of memory|oom-kill|killed process'. В них важны контекст события, имя и PID завершённого процесса, а также признаки cgroup. Для события из предыдущей загрузки, если журнал сохранён, используйте -b -1.

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

Как сделать, чтобы swap включался после перезагрузки?

Для автоматического включения swap при старте системы недостаточно выполнить swapon: эта команда активирует область только до перезагрузки. Уже созданный swap нужно корректно указать в /etc/fstab. Для swap-раздела обычно используют UUID, поскольку имя устройства может измениться.

Перед изменением сохраните исходный /etc/fstab, проверьте тип и UUID целевого устройства. Ошибка в этом файле может повлиять на загрузку системы, поэтому не откладывайте проверку до перезагрузки. После правки выполните sudo swapon -a: команда включает области swap из /etc/fstab, которые ещё не активны. Затем проверьте результат через swapon --show.

swapon -a не создаёт swap и не исправляет ошибочную запись в fstab. Порядок создания swap-файла и допустимость его использования зависят от файловой системы, версии ядра и дистрибутива, поэтому для этого используйте официальную документацию целевой ОС.

Почему используется swap, хотя MemAvailable ещё не равен нулю?

Это не обязательно проблема. Ядро может заранее выгрузить давно неиспользуемые анонимные страницы в swap, сохраняя RAM для файлового кэша и активной работы. Занятый swap после краткого пика может оставаться занятым до повторного обращения к этим страницам. Важнее проверить текущие si и so в vmstat.

Можно ли очистить swap на рабочем сервере?

Можно, но не как штатную реакцию на занятый swap. Сам факт занятого пространства не означает аварию: после краткого пика страницы могут оставаться в swap, пока приложения к ним не обратятся. Перед любой операцией сохраните free -h, swapon --show, результаты vmstat 1 5, список крупных процессов и сообщения OOM.

Далее сравните MemAvailable с объёмом занятого swap и оставьте запас для рабочего набора процессов и колебаний нагрузки. Универсального безопасного порога нет. Если решение обосновано, отключайте конкретную область командой sudo swapoff <путь>, а не все области сразу. sudo swapoff -a пытается отключить все активные swap-области из /proc/swaps, включая включённые вручную и отсутствующие в /etc/fstab.

После операции повторно проверьте память, активные области swap, журнал ядра и работоспособность нужных служб. При необходимости включите конкретную область через sudo swapon <путь> либо используйте sudo swapon -a для корректно описанных в /etc/fstab областей.

Отключает ли низкий vm.swappiness использование swap?

Нет. vm.swappiness не является переключателем swap и не гарантирует отсутствие подкачки. Параметр задаёт относительный вес выгрузки анонимных страниц в swap по сравнению с освобождением файлового кэша. Менять его стоит только после фиксации исходных показателей и проверки эффекта на конкретной нагрузке.