Перейти к основному содержимому
Вернуться в категорию

Обнаружение и устранение утечки памяти

Обнаружение и устранение утечек памяти на Linux-серверах, определение процесса, потребляющего RAM, и применение краткосрочных и долгосрочных решений.

Время чтения: 13 мин Устранение неполадок
памятьутечка памятиRAMvalgrindsmemlinuxпроизводительность

Содержание

Введение

Утечка памяти происходит, когда приложение не освобождает должным образом используемую память, что приводит к непрерывному росту использования RAM со временем. В конечном итоге система исчерпывает память, пространство подкачки заполняется, и сервер замедляется или зависает.

Симптомы

Типичные признаки утечки памяти:

  • Использование RAM непрерывно растёт (возвращается к норме после перезапуска)
  • Доступная память в free -h постепенно уменьшается
  • Использование подкачки растёт
  • Приложение замедляется со временем
  • OOM-killer активируется и убивает процессы

Шаг 1: Проверка текущего состояния памяти

hljs bash
# Общее состояние памяти
free -h

# Подробная информация о памяти
cat /proc/meminfo

# Журналы OOM-killer
dmesg | grep -i 'oom\|killed process\|out of memory'

Шаг 2: Какой процесс потребляет больше всего памяти?

hljs bash
# Сортировка по использованию памяти
ps aux --sort=-%mem | head -20

# Мониторинг в реальном времени с top
top
# Нажмите 'M' для сортировки по памяти

# Более детальный анализ памяти с smem
sudo apt install smem -y
smem -r -k | head -20

Шаг 3: Подтверждение утечки памяти

hljs bash
# Найти PID конкретного процесса
pgrep -f app_name

# Записывать использование памяти каждые 30 секунд
while true; do
    echo "$(date): $(cat /proc/PID/status | grep VmRSS)"
    sleep 30
done

Шаг 4: Решения для конкретных приложений

Утечка памяти Node.js

hljs bash
# Установить лимит памяти Node.js
node --max-old-space-size=512 app.js

# PM2 автоперезапуск при достижении лимита памяти
pm2 start app.js --max-memory-restart 500M

Утечка памяти PHP-FPM

hljs bash
# /etc/php/8.x/fpm/pool.d/www.conf
# pm.max_requests = 500
# memory_limit = 256M

Шаг 5: Экстренные решения

hljs bash
# Очистить кэш страниц (безопасно)
sync && echo 1 > /proc/sys/vm/drop_caches

# Перезапустить сервис
sudo systemctl restart service_name

# Лимит памяти через systemd
# [Service]
# MemoryMax=512M

# Создать файл подкачки
sudo fallocate -l 2G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
echo '/swapfile none swap sw 0 0' | sudo tee -a /etc/fstab

Заключение

Для устранения утечек памяти сначала определите с помощью ps aux и smem, какой процесс потребляет память, затем подтвердите утечку, отслеживая рост со временем. В краткосрочной перспективе перезапустите утекающий сервис и примените лимит памяти через systemd. Для постоянного исправления изучите исходный код приложения с помощью таких инструментов, как Valgrind (C/C++), heapdump (Node.js) или jmap (Java).