Как найти и устранить утечку памяти на Linux-сервере

05 Sep 2026, 05:02:00
Утечка памяти — это ситуация, при которой процесс продолжает занимать оперативную память, хотя используемые им данные уже не нужны. Со временем потребление RAM может увеличиваться, что приводит к снижению производительности сервера, запуску OOM Killer, остановке отдельных сервисов и в некоторых случаях — к полной недоступности приложений.
На Linux-сервере причиной роста потребления памяти может быть как ошибка в конкретном приложении, так и неправильная конфигурация сервисов, слишком большое количество процессов или высокая нагрузка.

Как понять, что на сервере есть проблема с памятью

Первый признак — постепенное увеличение занятой оперативной памяти.
Проверить общее состояние памяти можно командой:
free -hНапример:
 
Особое внимание стоит обратить на значение available. Показатель free сам по себе не означает, что память заканчивается: Linux использует свободную RAM для кеширования.
Если же available постоянно уменьшается, swap активно используется, а потребление памяти растёт, необходимо искать процесс, который занимает RAM.

Как найти процесс, который использует больше всего памяти

Для быстрого просмотра процессов можно использовать:
top

В top нажмите: Shift + M
После этого процессы будут отсортированы по использованию оперативной памяти.


Также можно сразу вывести наиболее «тяжёлые» процессы:
ps aux --sort=-%mem | head -20
Команда покажет первые 20 процессов с наибольшим потреблением RAM.
Например:


На этом этапе важно определить не только самый большой процесс, но и динамику его потребления памяти.
Большой процесс не обязательно является причиной утечки. Например, база данных может быть настроена на использование нескольких гигабайт RAM и работать совершенно нормально.

Что такое RSS, VSZ и %MEM

При анализе ps и top можно встретить несколько показателей.
RSS (Resident Set Size) — объём физической оперативной памяти, который процесс в данный момент использует.
VSZ (Virtual Size) — общий объём виртуального адресного пространства процесса. Он может быть значительно больше фактически используемой RAM.
%MEM — процент физической оперативной памяти сервера, используемый процессом.
Для поиска утечек памяти особенно полезно наблюдать за RSS.
Например, если один и тот же процесс постепенно увеличивает RSS:
200 MB
350 MB
600 MB
900 MB
1.5 GB
2.5 GB
и при этом его потребление не возвращается к прежнему уровню, это может указывать на утечку памяти.

Как проверить память конкретного процесса

Для более подробной информации можно посмотреть /proc.
Например, для процесса с PID 1020:
cat /proc/1020/status

Обратите внимание на параметры:
VmSize:
VmRSS:
VmData:
VmSwap:

Особенно важен:
VmRSS

Он показывает объём физической памяти, используемой процессом.
Также можно посмотреть карту памяти:
cat /proc/1020/smaps
Однако smaps содержит большое количество информации, поэтому для первичной диагностики обычно достаточно top, ps и /proc//status.

Как определить, действительно ли память постепенно расходуется

Однократной проверки недостаточно.
Если проблема возникает через несколько часов или дней, необходимо наблюдать за процессом в течение определённого периода.
Например:
watch -n 10 'ps -o pid,ppid,%mem,rss,vsz,cmd -p 1020'

Команда будет обновлять информацию каждые 10 секунд.
Если RSS процесса постоянно увеличивается:
200 MB
350 MB
620 MB
750 MB
900 MB

это повод исследовать приложение подробнее.
Для длительного мониторинга можно периодически записывать показатели в лог или использовать системы мониторинга сервера.

Не всякое увеличение памяти является утечкой

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

Проверка swap

Если оперативной памяти недостаточно, Linux начинает использовать swap.
Проверить его использование:
free -h
или:
swapon --show
Активное использование swap может свидетельствовать о нехватке RAM, но само по себе также не доказывает наличие утечки.
Если swap постоянно заполняется, необходимо определить, какой процесс потребляет память и почему.

Как найти OOM Killer

Если оперативная память полностью закончилась, Linux может запустить OOM Killer (Out Of Memory Killer). Он выбирает процессы и принудительно завершает их, чтобы освободить память.
Проверить сообщения ядра можно:
dmesg -T | grep -i -E 'oom|out of memory|killed process'
На системах с systemd также можно использовать:
journalctl -k | grep -i -E 'oom|out of memory|killed process'
Например:
Out of memory: Killed process 2212 (php-fpm)

Это означает, что ядро завершило процесс php-fpm из-за нехватки памяти.
В таком случае необходимо выяснить, почему память закончилась. Простое увеличение RAM не всегда устраняет проблему.

Проверка количества процессов

Иногда проблема связана не с одной утечкой, а с большим количеством процессов.
Например, сервер может создавать сотни или тысячи процессов PHP-FPM, Apache или другого сервиса.
Проверить количество процессов:
ps aux | wc -l

Для подсчёта процессов конкретного пользователя:
ps -u www-data | wc -l

Для PHP-FPM:
pgrep -c php-fpm

Если количество процессов постоянно увеличивается и не возвращается к нормальному уровню, необходимо проверить настройки самого сервиса.
Например, для PHP-FPM важными параметрами являются:
pm.max_children
pm.max_requests
pm.max_spare_servers
pm.min_spare_servers

Слишком большое значение pm.max_children может привести к тому, что большое количество PHP-процессов одновременно займёт всю доступную RAM.

Параметр pm.max_requests

Параметр pm.max_requests позволяет ограничить количество запросов, которые один PHP-FPM worker обрабатывает перед перезапуском.
Например:
pm.max_requests = 500
Это может быть полезно, если конкретное PHP-приложение или расширение постепенно увеличивает потребление памяти.
После обработки заданного количества запросов worker завершается и создаётся новый.
Важно понимать, что pm.max_requests — это способ ограничить последствия утечки, а не устранить её причину. Если утечка находится в PHP-коде или расширении, необходимо найти и исправить источник проблемы.

Как проверить Apache

Если используется Apache, стоит обратить внимание на количество одновременно работающих процессов.
Например:
ps aux | grep apache2

или:
ps aux | grep httpd
Также можно посмотреть количество процессов:
pgrep -c apache2

Большое количество Apache worker'ов может значительно увеличить потребление RAM.
Необходимо проверить настройки MaxRequestWorkers, используемый MPM и среднее потребление памяти одним worker'ом.

Как проверить MySQL или MariaDB

Базы данных часто являются одним из самых крупных потребителей RAM на сервере.
Проверить процесс:
ps aux --sort=-%mem | grep -E 'mysql|mariadb'

Однако большой объём памяти у MariaDB или MySQL не обязательно является проблемой.
База данных использует кеши и буферы для ускорения работы. Поэтому необходимо анализировать конфигурацию:
mysql -e "SHOW VARIABLES LIKE 'innodb_buffer_pool_size';"

Также следует учитывать общий объём RAM сервера и память, необходимую другим сервисам.
Например, сервер с 16 GB RAM, на котором база данных использует 12 GB, а ещё работают Nginx, PHP-FPM, Redis и другие сервисы, может столкнуться с нехваткой памяти даже при нормальной работе самой базы данных.

Как отличить утечку от обычной высокой нагрузки

Полезно сравнить потребление памяти с нагрузкой.
Например:
Вариант 1:
Количество запросов ↑
Использование RAM ↑
Количество процессов ↑
Такое поведение может быть нормальным при увеличении нагрузки.

Вариант 2:
Количество запросов → стабильно
CPU → стабильно
RAM → постоянно ↑
Это уже значительно сильнее указывает на возможную утечку или неограниченное накопление данных.

Что делать при обнаружении утечки

После обнаружения подозрительного процесса необходимо определить источник проблемы.
Возможные причины:
  • ошибка в приложении;
  • неисправное PHP- или Python-расширение;
  • неправильная работа плагина;
  • большое количество кешируемых данных;
  • слишком высокие лимиты процессов;
  • ошибка в конфигурации сервиса;
  • длительно работающий процесс, который не освобождает память;
  • некорректная работа стороннего модуля.
Если проблема находится в собственном приложении, необходимо использовать инструменты профилирования и анализировать код.
Для PHP, например, можно использовать профилировщики и инструменты диагностики памяти.
Для Python полезно применять tracemalloc, а для других языков существуют собственные инструменты профилирования.

Временные меры

Если утечка уже приводит к нехватке памяти, сначала необходимо восстановить нормальную работу сервера.
В зависимости от ситуации можно:
  • перезапустить проблемный сервис;
  • ограничить количество worker-процессов;
  • временно уменьшить нагрузку;
  • остановить необязательные сервисы;
  • увеличить объём RAM;
  • настроить swap как дополнительный механизм защиты.
Например:
systemctl restart php8.3-fpm
Однако перезапуск процесса следует рассматривать как временное решение. Если причина утечки не устранена, проблема появится снова.

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

Для серверов с критически важными сервисами рекомендуется постоянно отслеживать:
  • использование RAM;
  • использование swap;
  • количество процессов;
  • нагрузку CPU;
  • disk I/O;
  • потребление памяти отдельными сервисами;
  • количество OOM-событий;
  • uptime и перезапуски сервисов.
Полезно настроить мониторинг с сохранением истории. Тогда можно увидеть не только текущее состояние сервера, но и момент, когда потребление памяти начало увеличиваться.

Заключение

Поиск утечки памяти на Linux-сервере следует начинать не с перезапуска сервисов, а с анализа поведения системы.
Сначала необходимо проверить общую доступную память:
free -h
затем определить наиболее требовательные процессы:
ps aux --sort=-%mem | head -20
После этого следует наблюдать за потреблением RAM конкретным процессом и проверить системные логи на наличие OOM-событий:
journalctl -k | grep -i -E 'oom|out of memory|killed process'
Главная задача — установить, какой процесс потребляет память, почему его потребление растёт и связано ли это с реальной нагрузкой.
Перезапуск сервиса или увеличение объёма RAM могут временно решить проблему, но при настоящей утечке необходимо устранить её источник — неисправный код, модуль, расширение или неправильную конфигурацию сервиса.

Премиум выделенные серверы

Смотреть конфигурации