Кончилась память: 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
Что сделать сейчас
- Добавьте подкачку, если её нет. Это не замена памяти, но переживать всплески она помогает:
fallocate -l 2G /swapfile && chmod 600 /swapfile
mkswap /swapfile && swapon /swapfile
echo '/swapfile none swap sw 0 0' >> /etc/fstab
-
Ограничьте аппетиты служб. MySQL —
innodb_buffer_pool_size, PostgreSQL —shared_buffersиwork_mem, PHP-FPM —pm.max_children, Node —--max-old-space-size, Gunicorn и Puma — число воркеров. Считайте по формуле: пиковое потребление одного воркера, умноженное на их число, плюс база, плюс 500 МБ системе — должно уместиться в память ступени. -
Поставьте лимит через systemd, чтобы вредная служба не утягивала за собой остальные:
[Service]
MemoryMax=1G
Restart=always
RestartSec=10
Служба с лимитом будет убита первой и в границах своего cgroup, а база и SSH выживут.
- Защитите важное от выбора ядра:
systemctl set-property postgresql.service OOMScoreAdjust=-800
Когда пора на ступень выше
Если после уборки и лимитов приложение всё равно не помещается, а лишнего в системе нет, добавьте памяти: ряд ступеней — 2, 4, 8, 16, 24, 32 ГБ. Переход возможен только вверх, с доплатой за оставшиеся дни оплаченного срока. Подробнее — Память и подкачка.
Частые ошибки
- Просто перезапускать службу по расписанию. Утечка остаётся, а вы теряете соединения клиентов дважды в сутки.
- Отключать OOM killer. Без него ядро уйдёт в бесконечную подкачку, и машина повиснет целиком — это хуже, чем потеря одного процесса.
- Делать огромный swap. Машина не упадёт, но будет работать в десятки раз медленнее.
- Ставить на VDS-1 всё сразу. Панель мониторинга, база, приложение и Docker в 2 ГБ не помещаются: разнесите или возьмите ступень выше.
Настройте оповещение при заполнении памяти на 85 %, чтобы узнавать о проблеме до падения, — простой рецепт в статье Оповещения о падении сайта.