Перейти к содержимому
VDS · Решение проблем

Кончилась память: OOM killer

Как узнать, что процесс убило ядро из-за нехватки памяти, кто в этом виноват и какие настройки не дадут ситуации повториться.

Обновлено 23 августа 2026 г.

Сайт внезапно перестал отвечать, база пропала из списка процессов, в журнале приложения ничего нет — типичная картина работы OOM killer. Когда память заканчивается, ядро выбирает самый «тяжёлый» процесс и завершает его без предупреждения.

Убедиться, что это он

dmesg -T | grep -i -E 'out of memory|oom-kill|killed process'
journalctl -k --since "1 hour ago" | grep -i oom
journalctl -u myapp --since today | tail -30

Характерная строка выглядит так:

Out of memory: Killed process 1841 (mysqld) total-vm:2841244kB, anon-rss:1043100kB

В ней сразу есть жертва и объём, который она занимала. Заодно посмотрите, сколько раз перезапускалась служба: systemctl show myapp -p NRestarts.

График памяти на вкладке «Обзор» в панели /hosting/vds/<id> подтвердит картину: рост до потолка и резкий обрыв.

Кто виноват на самом деле

Ядро убивает не виновника, а самого крупного. Часто гибнет база данных, хотя память съел рабочий процесс приложения. Разбирайтесь по графику за неделю:

  • пила — утечка: потребление растёт, перезапуск сбрасывает, всё повторяется;
  • всплеск в момент задачи — тяжёлая операция: импорт, сборка, генерация отчёта;
  • ровный рост при росте нагрузки — воркеров больше, чем позволяет ступень.

Список самых прожорливых на данный момент:

ps aux --sort=-%mem | head -10
systemd-cgtop -m

Что сделать сейчас

  1. Добавьте подкачку, если её нет. Это не замена памяти, но переживать всплески она помогает:
fallocate -l 2G /swapfile && chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
  1. Ограничьте аппетиты служб. MySQL — innodb_buffer_pool_size, PostgreSQL — shared_buffers и work_mem, PHP-FPM — pm.max_children, Node — --max-old-space-size, Gunicorn и Puma — число воркеров. Считайте по формуле: пиковое потребление одного воркера, умноженное на их число, плюс база, плюс 500 МБ системе — должно уместиться в память ступени.

  2. Поставьте лимит через systemd, чтобы вредная служба не утягивала за собой остальные:

[Service]
MemoryMax=1G
Restart=always
RestartSec=10

Служба с лимитом будет убита первой и в границах своего cgroup, а база и SSH выживут.

  1. Защитите важное от выбора ядра:
systemctl set-property postgresql.service OOMScoreAdjust=-800

Когда пора на ступень выше

Если после уборки и лимитов приложение всё равно не помещается, а лишнего в системе нет, добавьте памяти: ряд ступеней — 2, 4, 8, 16, 24, 32 ГБ. Переход возможен только вверх, с доплатой за оставшиеся дни оплаченного срока. Подробнее — Память и подкачка.

Частые ошибки

  • Просто перезапускать службу по расписанию. Утечка остаётся, а вы теряете соединения клиентов дважды в сутки.
  • Отключать OOM killer. Без него ядро уйдёт в бесконечную подкачку, и машина повиснет целиком — это хуже, чем потеря одного процесса.
  • Делать огромный swap. Машина не упадёт, но будет работать в десятки раз медленнее.
  • Ставить на VDS-1 всё сразу. Панель мониторинга, база, приложение и Docker в 2 ГБ не помещаются: разнесите или возьмите ступень выше.

Настройте оповещение при заполнении памяти на 85 %, чтобы узнавать о проблеме до падения, — простой рецепт в статье Оповещения о падении сайта.