Когда на малом VDS внезапно «умирает» процесс, в системном журнале часто виден след: OOM‑killer. Это не баг, а защитный механизм ядра Linux: когда оперативная память заканчивается, ядро принудительно завершает наименее «ценный» процесс. Задача администратора — сделать так, чтобы до этого не доходило, а если уж дошло — выжил хотя бы SSH и критичные сервисы.
Как Linux использует память: короткий ликбез
В Linux RAM — не просто «свободно/занято». Значительную часть занимает кэш страниц (page cache) и кеши dentry/inode. Они выталкиваются первыми при росте нагрузки, поэтому «свободной» памяти может быть мало, но система работает стабильно. Нестабильность начинается, когда:
- растут анонимные страницы (heap/stack процессов);
- падает эффективность освобождения кэшей;
- нет swap или он исчерпан;
- жесткие лимиты (cgroups) срабатывают раньше, чем общая система.
Отсюда инструменты: swap (включая компрессированный zram), параметры sysctl (vm.overcommit_memory, vm.swappiness и другие), а также осознанная изоляция сервисов в cgroup через systemd. Если ваш проект на виртуальном хостинге уже упирается в RAM, рассмотрите переход на VDS — это даст контроль над ядром, swap и cgroup.
Swap: зачем, сколько и как
Swap — это страховка от кратковременных пиков. Он не заменяет RAM и не «ускоряет» сервер, но дает ядру пространство для «холодных» страниц, снижая шанс OOM. Для малых VDS практична связка: компрессированный zram как быстрый swap в памяти плюс небольшой swap‑файл на диске.
Базовый рецепт swap‑файла
sudo fallocate -l 1G /swapfile
sudo chmod 600 /swapfile
sudo mkswap /swapfile
sudo swapon /swapfile
sudo swapon --show
Сделайте swap постоянным через /etc/fstab:
/swapfile none swap sw,pri=10 0 0
Рекомендации по размеру: на малом VDS (1–4 ГБ RAM) начните с 0.5–1× от RAM суммарно, учитывая zram (ниже), и смотрите по реальной нагрузке. Для баз данных и latency‑критичных систем держите swap умеренным и следите за I/O.
ZRAM: компрессированный swap в ОЗУ
zram создает блок‑устройство в оперативной памяти, где данные хранятся в сжатом виде. Сжатие (LZ4/ZSTD) даёт «виртуальное» увеличение доступной памяти при низких задержках. Типовой сценарий: zram со старшим приоритетом, дисковый swap с младшим.
Вариант 1: zram‑tools (Debian/Ubuntu)
sudo apt update
sudo apt install zram-tools
Отредактируйте /etc/default/zramswap (если файла нет, создайте):
ALGO=zstd
PERCENT=50
PRIORITY=100
Примените:
sudo systemctl enable zramswap --now
sudo zramctl
sudo swapon --show
PERCENT=50 означает «создать zram размером 50% от RAM». Для 2 ГБ RAM это ~1 ГБ сжатого swap, который фактически влезет в меньший объём за счёт компрессии.
Вариант 2: zram‑generator (RHEL/Fedora/новые дистрибутивы)
sudo dnf install zram-generator
Создайте /etc/systemd/zram-generator.conf:
[zram0]
zram-size = ram / 2
compression-algorithm = zstd
swap-priority = 100
Активируйте:
sudo systemctl daemon-reload
sudo systemctl restart systemd-zram-setup@zram0.service
sudo zramctl
sudo swapon --show
Одновременный zram и дисковый swap: приоритеты
Убедитесь, что у zram приоритет выше (например, 100), а у дискового swap ниже (например, 10). Тогда ядро сперва использует быстрый компрессированный swap и только затем — медленный диск.

Sysctl‑параметры: пресеты без фанатизма
Создайте файл /etc/sysctl.d/99-memory.conf и задайте базовые значения. Два проверенных профиля:
Профиль A: универсальный малый VDS (веб‑приложение, очереди, небольшая БД)
vm.swappiness = 80
vm.vfs_cache_pressure = 100
vm.overcommit_memory = 2
vm.overcommit_ratio = 120
vm.min_free_kbytes = 65536
vm.page-cluster = 0
Пояснения:
vm.swappiness=80— позволяет активнее выносить «холодные» страницы в zram, снижая вероятность резкого OOM.vm.overcommit_memory=2иvm.overcommit_ratio=120— строгий контроль overcommit: ядро не обещает программам больше памяти, чем доступно по формуле (RAM + swap × ratio). Это уменьшает риск внезапного OOM.vm.page-cluster=0— уменьшает «чтение пачками» при подкачке, что полезно для интерактивности на медленном диске.
Профиль B: latency‑чувствительные сервисы
vm.swappiness = 20
vm.vfs_cache_pressure = 200
vm.overcommit_memory = 2
vm.overcommit_ratio = 100
vm.min_free_kbytes = 131072
vm.page-cluster = 1
Идея: меньше полагаться на swap, агрессивнее чистить кеши, держать чуть больший «воздушный зазор» свободной памяти. Применение настроек:
sudo sysctl --system
vm.overcommit_memory без страха
vm.overcommit_memory имеет три режима:
- 0 — эвристика ядра (может быть непредсказуемой на малых VDS).
- 1 — разрешить любой overcommit (максимальный риск OOM).
- 2 — ограничивать выделение в пределах расчётного лимита (
vm.overcommit_ratio).
На малом VDS безопаснее режим 2. Он откажет в выделении памяти раньше (например, malloc() вернёт ошибку), чем сервер уйдёт в своп‑шторм и OOM. Это легче отлавливать в приложении и логах.
OOM‑killer: понять и приручить
Когда памяти не хватает, OOM‑killer выбирает жертву по баллам (oom_score). На результат можно влиять через oom_score_adj (от −1000 до 1000). Чем меньше, тем «ценнее» процесс для системы.
Защитим SSH и критичные демоны
Сделайте systemd‑override для SSH:
sudo systemctl edit sshd
В открывшемся редакторе добавьте:
[Service]
OOMScoreAdjust=-900
Перезапустите:
sudo systemctl daemon-reload
sudo systemctl restart sshd
Проверьте:
cat /proc/$(pidof sshd)/oom_score_adj
Аналогично можно защитить прокси, watchdog или легкий админский агент. Не злоупотребляйте: если «неубиваемых» процессов много, OOM‑killer выберет что‑то другое, возможно важное.
Ограничения по памяти на уровень сервиса
systemd позволяет задавать cgroup‑лимиты и реакцию на OOM:
[Service]
MemoryMax=512M
MemoryHigh=384M
OOMPolicy=restart
MemoryHigh сигнализирует ядру дросселировать процесс при приближении к лимиту, MemoryMax — жесткий предел. OOMPolicy задает поведение systemd при OOM внутри cgroup (например, перезапустить сервис).
PHP‑FPM, воркеры и «тихие пожиратели RAM»
Частая причина OOM — слишком много процессов. Для PHP‑FPM, Node.js/PM2, Python‑воркеров и Java‑сервисов пересчитайте пулы и ограничьте рост:
- PHP‑FPM: подберите
pm,pm.max_childrenи лимиты памяти расширений. - Node.js: учтите дефолтные лимиты V8 и используйте
--max-old-space-sizeгде нужно. - Python/uwsgi/gunicorn: контролируйте число воркеров и используйте перезапуски по памяти.
Лучший способ — задать разумный предел на уровне systemd через MemoryMax и наблюдать фактическое потребление.
Мониторинг и диагностика memory pressure
Минимальный набор команд для наблюдения:
free -h
vmstat 1
Топ прожорливых процессов и их OOM‑метрики:
ps -eo pid,cmd,pmem,rss,oom_score,oom_score_adj --sort=-rss | head -n 20
Pressure Stall Information (PSI) показывает «время под давлением»:
cat /proc/pressure/memory
Строки some и full растут — значит, задачи ждут память, а система «давится». Ищите всплески перед инцидентами.
Логи OOM‑killer в dmesg/journal:
dmesg -T | grep -i oom
journalctl -k -g OOM -n 100

Тест под нагрузкой: лучше сломать на стенде
Инструменты для репродукции проблем памяти:
sudo apt install stress-ng
stress-ng --vm 1 --vm-bytes 80% --timeout 60s
Или проверка на ошибки RAM:
sudo apt install memtester
sudo memtester 256M 1
Параллельно смотрите PSI, swap‑активность и отклики сервисов. Если под нагрузкой система резко уходит в swap на диск — уменьшите swappiness или увеличьте долю zram. Если ловите OOM — проверьте vm.overcommit*, лимиты cgroup и размер swap. Быстрый стенд для таких экспериментов удобнее поднять на отдельном VDS.
Практический пресет для малого VDS: пошагово
- Включите zram (50% RAM, приоритет 100).
- Добавьте небольшой дисковый swap‑файл (0.5–1 ГБ, приоритет 10).
- Примените профиль sysctl:
vm.overcommit_memory=2,vm.overcommit_ratio=120,swappiness=80,page-cluster=0. - Задайте
OOMScoreAdjust=-900для SSH и одного‑двух критичных сервисов. - Ограничьте прожорливые службы через
MemoryHigh/MemoryMax. - Протестируйте
stress-ng, наблюдайте PSI и логи OOM. - Зафиксируйте изменения в конфигурациях, перезагрузите и убедитесь, что всё поднимается автоматически.
Тонкости и подводные камни
- Дисковый swap на медленном SSD/HDD может вызывать задержки. Делайте ставку на zram, а диск оставляйте как «вторую линию».
- Слишком высокий
swappinessбез zram приведет к «липкому» дисковому swap и лагам. - Жесткий overcommit (
vm.overcommit_memory=2) может ломать запуск редких приложений, ожидающих «много памяти на старте». Решение — временно ослабить лимит или поднятьvm.overcommit_ratio. - Не защищайте от OOM всё подряд. Смысл в том, чтобы ядро могло безопасно выгрузить наименее важное.
- Следите за
journalctl: если видите постоянные предупреждения о throttling поMemoryHigh, значит, лимит слишком tight.
Планируете переезд и подбор панели управления? Смотрите сравнение актуальных панелей для VDS: что выбрать для администрирования, и пошаговую инструкцию по миграции с шареда: как переехать на VDS без простоев.
Итог
На малом VDS стабильность достигается комбинацией мер: быстрый компрессированный swap через zram, аккуратный дисковый swap, строгий vm.overcommit_memory=2 с разумным vm.overcommit_ratio, корректный swappiness и явные границы для прожорливых сервисов через cgroup. Добавьте защиту SSH от OOM, наблюдайте PSI и тестируйте под нагрузкой — и «внезапные Kill» уйдут в прошлое.
Правильная настройка памяти — это не разовый твик, а цикл: замер, изменение, проверка, откат при необходимости. Документируйте решения и держите план теста под рукой.


