Linux OOMКритическая

Out of Memory (OOM) ошибка в Linux: причины и способы решения

Статья подробно объясняет ошибку 'Out of Memory' (OOM) в Linux, механизм работы OOM killer, основные причины нехватки оперативной памяти и предоставляет конкретные пошаговые инструкции по диагностике, немедленному исправлению и профилактике проблемы.

Обновлено 15 февраля 2026 г.
15-30 мин
Средняя
FixPedia Team
Применимо к:Linux (любой дистрибутив)Systemd-based системыDocker/Kubernetes средыСерверы и рабочие станции

Что означает ошибка Out of Memory (OOM)

Ошибка Out of Memory (OOM) в Linux — это не сообщение в стиле Windows, а действие ядра операционной системы. Когда система физически исчерпывает всю доступную оперативную память (RAM) и место в swap-файле/разделе, ядро активирует механизм OOM killer (убийца при нехватке памяти).

Его цель — сохранить работоспособность системы в целом, принудительно завершив один или несколько процессов, которые потребляют наибольший объём памяти. Типичный симптом: процесс (например, java, python, mysqld, контейнер Docker) внезапно завершается с сообщением в логах:

[12345.678] Out of memory: Kill process 1234 (some_process) score 500 or sacrifice child
[12345.679] Killed process 1234 (some_process) total-vm:1234567kB, anon-rss:987654kB, file-rss:0kB

Система может стать неотзывчивой, а после завершения «виновника» — вернуться в нормальное состояние.

Причины возникновения

Причины нехватки памяти обычно делятся на несколько категорий:

  1. Утечки памяти (Memory Leaks) в приложениях. Программа (например, на Java, Python, C++) постепенно выделяет память под объекты, но не освобождает её после использования. Со временем потребление растёт до критических значений.
  2. Неправильная конфигурация приложений. Чрезмерно большой размер кучи (heap) для JVM (-Xmx), кэширование слишком больших объёмов данных без ограничений, неоптимальные настройки веб-сервера (например, worker_processes + worker_connections в Nginx).
  3. Физически недостаточный объём RAM. Запуск нескольких требовательных приложений (виртуальные машины, базы данных, тяжёлые IDE) на сервере с малым количеством памяти.
  4. Отсутствие или недостаточный размер swap-пространства. Swap служит «подушкой безопасности». Если его нет или он слишком мал, первое же существенное нехватка RAM приведёт к OOM.
  5. Атака или вредоносное ПО. Например, DDoS-атака, вызывающая создание множества соединений, или скрипт, бесконечно создающий процессы/объекты в памяти.
  6. «Зомби»-процессы или неосвобождаемые ресурсы ядра. Хотя реже, но некоторые ядерные структуры (например, неосвобождённые inode или dentry) могут накапливаться.

Способы решения

Способ 1: Диагностика и мониторинг (первый шаг всегда)

Прежде чем что-то менять, точно определите источник проблемы.

  1. Проверьте системный журнал на наличие записей OOM.
    # Поиск в логах systemd (journalctl)
    journalctl -k | grep -i -E "killed process|out of memory"
    
    # Или через dmesg
    dmesg | grep -i oom
    

    В выводе будет PID и имя процесса (some_process), который был убит. Это ваш главный подозреваемый.
  2. Оцените текущее использование памяти.
    # Установите утилиту, если нет (для Debian/Ubuntu)
    sudo apt-get install htop
    
    # Запустите htop (нажимайте F6 для сортировки по MEM%)
    htop
    
    # Или используйте встроенные команды
    free -h  # Покажет общую картину RAM+Swap
    ps aux --sort=-%mem | head -10  # Топ-10 процессов по памяти
    
  3. Для контейнеров Docker/Kubernetes:
    # Показать контейнеры с их потреблением памяти
    docker stats --no-stream
    
    # Проверить логи контейнера на наличие OOM
    docker logs <container_id> 2>&1 | grep -i oom
    

    В Kubernetes событие OOM будет в kubectl describe pod <pod_name>.

Способ 2: Немедленные действия для стабилизации системы

Если система уже в кризисе, но ещё реагирует:

  1. Вручную завершите «пожирателя» памяти (используйте PID из логов или htop).
    sudo kill -9 <PID>
    

    Внимание: -9 (SIGKILL) — грубая сила. Сначала попробуйте обычный kill <PID>.
  2. Очистите кэши файловой системы (может помочь, если проблема в кэшах). Это безопасно, ядро заново заполнит их по мере необходимости.
    # Очистка только кэша страниц (pagecache), dentries и inodes
    sudo sync  # Синхронизируем данные на диск
    echo 3 | sudo tee /proc/sys/vm/drop_caches
    

    Не выполняйте эту команду слишком часто и не на продакшн-сервере без понимания последствий.
  3. Временно увеличьте swap-пространство (если его мало или нет), чтобы дать системе «передышку».
    # Создаём файл подкачки размером 2ГБ
    sudo fallocate -l 2G /swapfile
    sudo chmod 600 /swapfile
    sudo mkswap /swapfile
    sudo swapon /swapfile
    
    # Чтобы включить после перезагрузки, добавьте в /etc/fstab:
    # /swapfile none swap sw 0 0
    

    Проверьте: free -h.

Способ 3: Настройка поведения OOM killer (OOMPolicy)

Вы можете повлиять на то, какой процесс OOM killer выберет в первую очередь.

  1. Используйте oom_score_adj для критичных процессов. У каждого процесса есть oom_score (от 0 до 1000), рассчитанный на основе потребления памяти. Чем выше, тем вероятнее его убийство. Вы можете снизить этот балл для важных сервисов.
    # Посмотреть текущий oom_score для процесса
    cat /proc/<PID>/oom_score
    
    # Установить низкий приоритет на убийство (например, -500) для PID 1234
    sudo echo -500 > /proc/1234/oom_score_adj
    
    # Для постоянной настройки лучше использовать systemd-юнит
    # В файле сервиса /etc/systemd/system/<service>.service добавьте:
    # [Service]
    # OOMScoreAdjust=-500
    

    Важно: Не ставьте oom_score_adj = -1000 (запрет на убийство) для всех процессов. Это может привести к полному зависанию системы.
  2. Изменение политики переcommitting памяти (vm.overcommit_memory). По умолчанию (0) ядро использует эвристику. Режим 1 (Always overcommit) позволяет выделять память без ограничений, но риск OOM возрастает. Режим 2 (Don't overcommit) строго проверяет, достаточно ли памяти+swap.
    # Проверить текущее значение
    cat /proc/sys/vm/overcommit_memory
    
    # Временно установить режим "не переcommittить" (2)
    sudo sysctl vm.overcommit_memory=2
    sudo sysctl vm.overcommit_ratio=100  # % от RAM+Swap, который можно выделить
    
    # Для постоянной настройки добавьте в /etc/sysctl.conf:
    # vm.overcommit_memory = 2
    # vm.overcommit_ratio = 100
    

    Внимание: Режим 2 может привести к тому, что приложения начнут падать с Cannot allocate memory ещё до срабатывания OOM killer, что иногда удобнее для отладки.

Способ 4: Устранение коренной причины

Это самый важный и долгосрочный шаг.

  1. Для Java-приложений: Проверьте и уменьшите размер кучи (-Xmx, -Xms) в параметрах JVM. Используйте инструменты вроде jstat, jmap, VisualVM для анализа heap dump.
    # Пример запуска с ограничением heap до 2ГБ
    java -Xmx2g -jar your_app.jar
    
  2. Для веб-серверов (Nginx/Apache): Оптимизируйте количество рабочих процессов/потоков под имеющуюся память. Убедитесь, что нет бесконечного кэширования.
  3. Поиск утечек памяти:
    • Для C/C++: Используйте valgrind --leak-check=yes.
    • Для Python: tracemalloc, objgraph, memory_profiler.
    • Для Node.js: heapdump, clinic.js.
    • Общие утилиты: smem -t -p (показывает PSS — Proportional Set Size), cat /proc/<PID>/smaps.
  4. Апгрейд железа. Если нагрузка закономерна и приложение оптимизировано, возможно, просто не хватает физической RAM для рабочих задач.
  5. Для контейнеров (Docker/K8s): Корректно задавайте лимиты памяти (--memory, --memory-swap в Docker; resources.limits.memory в K8s). Без лимитов контейнер может «съесть» всю память хоста.

Профилактика

  1. Внедрите мониторинг. Настройте алерты (в Zabbix, Prometheus/Grafana, Nagios) на ключевые метрики:
    • node_memory_MemAvailable_bytes (доступно памяти) < 10-15%
    • node_memory_SwapTotal_bytes и использование swap > 50%
    • container_spec_memory_limit_bytes (для контейнеров)
  2. Регулярно анализируйте логи. Добавьте в мониторинг парсинг логов journalctl на наличие «Killed process».
  3. Правильно настраивайте лимиты. Для всех сервисов (особенно в Docker/K8s) задавайте как requests (гарантированный минимум), так и limits (жёсткий потолок).
  4. Тестируйте под нагрузкой. Проводите нагрузочное тестирование (например, stress-ng, memtester) в staging-среде, чтобы увидеть поведение приложения при росте потребления памяти.
  5. Следите за версиями ПО. Утечки памяти часто исправляются в обновлениях. Регулярно обновляйте ОС и критичные приложения.

Заключение

Ошибка Out of Memory в Linux — это сигнал о том, что система исчерпала свои ресурсы. Механизм OOM killer — это последняя линия обороны, а не решение проблемы. Ваша задача — диагностировать «пожирателя» памяти через логи, стабилизировать систему (завершив процесс или добавив swap), а затем устранить коренную причину: утечку, неправильную конфигурацию или физический недостаток RAM. Профилактика через мониторинг и грамотное выделение лимитов — лучший способ избежать внезапных падений сервисов в будущем.

Часто задаваемые вопросы

Что такое OOM killer и почему он завершает мои процессы?
Можно ли полностью отключить OOM killer?
Как понять, какой процесс был убит OOM killer?
Повышение swap-пространства всегда решает проблему OOM?

Полезное

Диагностика: проверьте журналы на наличие OOM событий
Мониторинг: оцените текущее использование памяти
Краткосрочное решение: освободите память
Среднесрочное решение: настройте параметры OOM
Долгосрочное решение: устранение причины