65 лет полету человека в космос! Хостинг и домены со скидкой
до 22.04.2026 Подробнее
Выберите продукт

Debian/Ubuntu: Cannot allocate memory при fork и SSH — диагностика и исправление

Ошибки Cannot allocate memory, fork cannot allocate memory и ssh cannot allocate memory в Debian/Ubuntu часто связаны не только с нехваткой RAM, но и со swap, overcommit, лимитами процессов и OOM. Разберём, как быстро вернуть доступ по SSH, найти источник сбоя и не допустить повторения.
Debian/Ubuntu: Cannot allocate memory при fork и SSH — диагностика и исправление

Сообщения вида cannot allocate memory linux, fork cannot allocate memory или ssh cannot allocate memory появляются в момент, когда системе уже тяжело обслуживать новые процессы или выделять память. И почти всегда это не история уровня «просто закончилась оперативка».

На Debian и Ubuntu ошибка может быть связана с исчерпанием RAM, отсутствием swap, жёсткой политикой vm.overcommit_memory, лимитами на количество процессов, cgroup-ограничениями контейнера или сервиса, а также с обычной утечкой памяти в приложении.

Самый неприятный сценарий — когда перестаёт открываться новая SSH-сессия. Порт ещё отвечает, аутентификация может даже пройти, но дальше сервер уже не может породить shell или дочерний процесс. В этот момент важно не паниковать и не закрывать последнюю живую консоль.

Ниже разберём, как быстро отличить реальный дефицит памяти от лимитов процессов, какие команды запускать в первую очередь, как аккуратно вернуть сервер в рабочее состояние и что поменять, чтобы инцидент не повторился.

Что на самом деле означает Cannot allocate memory

Ошибка возникает, когда процесс просит ядро выделить память или создать дочерний процесс, а ядро не может гарантировать выполнение запроса. Очень часто это проявляется на вызове fork(), потому что даже для короткоживущего дочернего процесса нужны служебные структуры, таблицы страниц и ресурсы учёта.

Из-за этого симптоматика бывает обманчивой. В системе может оставаться часть памяти в page cache, но форк уже не проходит. Или RAM визуально ещё не заполнена на 100%, однако система уткнулась в CommitLimit, лимит контейнера или ограничение на количество процессов.

Ключевая мысль простая: fork cannot allocate memory не означает автоматически «физическая память полностью кончилась». Это более широкий сигнал о том, что ядро не может безопасно обслужить запрос на новый процесс или выделение памяти.

Типовые причины на Debian и Ubuntu

Закончилась RAM и нет swap

Это классический сценарий. PHP-FPM, база данных, Java, Node.js, очереди, Docker-контейнеры или просто слишком много воркеров постепенно занимают всю память. Если swap отсутствует или слишком мал, запас прочности у системы быстро заканчивается.

Есть RAM, но исчерпан commit limit

Linux учитывает не только занятую физическую память, но и объём виртуальной памяти, который процессы уже зарезервировали. На поведение влияет vm.overcommit_memory. Поэтому ошибка может появиться раньше, чем вы увидите «полный ноль» в обычном выводе free.

Слишком много процессов или потоков

Иногда первопричина — не память как таковая, а лавина процессов: runaway-воркеры, рекурсивный cron, ошибка в supervisor, неудачная конфигурация пула, форк-бомба. Каждый процесс потребляет память и системные ресурсы, поэтому лимит быстро упирается в потолок.

Лимиты systemd, контейнера или cgroup

На хосте память ещё может оставаться, но конкретный сервис уже умирает внутри собственных ограничений. Особенно часто это видно в Docker, Kubernetes и systemd unit с параметрами MemoryMax и TasksMax.

Утечки памяти

Если сервис медленно растёт часами или днями, авария обычно происходит не на пике нагрузки, а в случайный момент. Такие истории часто встречаются у веб-приложений, фоновых обработчиков, кэшей и долгоживущих воркеров.

FastFox VDS
Облачный VDS-сервер в России
Аренда виртуальных серверов с моментальным развертыванием инфраструктуры от 195₽ / мес

Если проект уже перерос базовый профиль нагрузки и вы регулярно упираетесь в память, стоит заранее пересмотреть размер инстанса или переехать на более подходящий VDS, где проще контролировать swap, лимиты и профиль сервисов.

Проверка процессов и использования памяти на Linux-сервере

Как проявляется проблема с SSH

Ошибка ssh cannot allocate memory означает, что серверу не хватает ресурсов даже на создание shell после логина. Сам sshd ещё может слушать порт и принимать соединение, но дальнейшая обработка уже ломается.

Часто это выглядит так:

ssh: fork: Cannot allocate memory

Или так:

-bash: fork: retry: Resource temporarily unavailable
-bash: fork: Cannot allocate memory

Сообщение Resource temporarily unavailable важно не меньше, чем Cannot allocate memory. Оно часто указывает на лимиты процессов, а не только на нехватку RAM. Поэтому диагностика должна быть шире, чем одна команда free -h.

Первичная диагностика: что смотреть сразу

Если у вас ещё осталась хотя бы одна рабочая сессия, не закрывайте её. Это аварийная точка входа. Задача на первом этапе — быстро понять, проблема в памяти, в процессных лимитах или в ограничении конкретного сервиса.

Проверить память и swap

free -h
swapon --show
cat /proc/meminfo | egrep 'MemAvailable|SwapTotal|SwapFree|Committed_AS|CommitLimit'

Смотрите прежде всего на MemAvailable, наличие swap и соотношение Committed_AS к CommitLimit. Если swap отсутствует, а доступная память почти нулевая, причина, скорее всего, в реальном дефиците памяти.

Проверить OOM killer

dmesg -T | egrep -i 'killed process|out of memory|oom'
journalctl -k -b | egrep -i 'killed process|out of memory|oom'

Если ядро уже кого-то убивало, в логах будут PID, имя процесса и объём памяти. Это обычно самый короткий путь к виновнику.

Найти самые прожорливые процессы

ps aux --sort=-%mem | head -20
ps -eo pid,ppid,user,cmd,%mem,%cpu,rss,vsz --sort=-rss | head -20

Ориентируйтесь на RSS и на общую сумму по группе процессов. Один процесс на 300 МБ может быть менее опасен, чем 30 воркеров по 120 МБ.

Проверить лимиты процессов

ulimit -a
cat /proc/sys/kernel/pid_max
cat /proc/sys/kernel/threads-max
ps -eLf | wc -l

Если число потоков и процессов близко к системным лимитам, форк может ломаться даже без абсолютного нуля по памяти.

Проверить ограничения systemd

systemctl show ssh -p MemoryCurrent -p MemoryMax -p TasksCurrent -p TasksMax
systemctl show php8.2-fpm -p MemoryCurrent -p MemoryMax -p TasksCurrent -p TasksMax
systemctl status

Подставьте свои юниты. Если у сервиса занижен MemoryMax или TasksMax, проблема может быть локальной, а не системной.

Как срочно вернуть сервер в чувство

На аварийном этапе цель простая: восстановить управляемость и не ухудшить ситуацию. Не запускайте тяжёлые диагностические утилиты, если сервер уже задыхается.

Если есть открытая SSH-сессия

Найдите самый тяжёлый процесс и попытайтесь остановить его мягко. Если не помогает — завершайте жёстко.

ps -eo pid,cmd,%mem,rss --sort=-rss | head -15
kill -TERM PID
sleep 3
kill -KILL PID

Обычно безопаснее начать с runaway-воркеров, дублирующихся контейнеров, зависших импортёров, очередей или тестовых процессов, а не с базы данных.

Если виноват конкретный сервис

systemctl stop php8.2-fpm
systemctl stop apache2
systemctl stop docker

Останавливайте только то, последствия чего вы понимаете. На production лучше отключить один проблемный юнит, чем вслепую уронить весь стек.

Если swap отсутствует

В аварийной ситуации swap-файл часто помогает вернуть SSH и дать системе немного воздуха. Это не панацея, но как временная страховка работает хорошо.

fallocate -l 1G /swapfile
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile
free -h

Если fallocate не подходит для вашей файловой системы, используйте альтернативу:

dd if=/dev/zero of=/swapfile bs=1M count=1024 status=progress
chmod 600 /swapfile
mkswap /swapfile
swapon /swapfile

Если после временной стабилизации вы планируете оставить swap насовсем, добавьте запись в /etc/fstab.

На проектах, где ресурсов уже не хватает даже после базовой оптимизации, полезно заранее планировать миграцию или расширение. Если вы как раз выбираете схему переноса, посмотрите материал про переезд с виртуального хостинга на VDS.

Роль vm.overcommit_memory

Параметр vm.overcommit_memory управляет тем, насколько оптимистично ядро относится к резервированию памяти приложениями.

  • 0 — эвристический режим по умолчанию;
  • 1 — почти всегда разрешать overcommit;
  • 2 — строгий режим, без выхода за commit limit.

Для большинства обычных серверов подходит 0. Если кто-то включил 2, некоторые приложения могут получать fork cannot allocate memory заметно раньше ожидаемого.

sysctl vm.overcommit_memory
sysctl vm.overcommit_ratio

Для диагностики можно временно вернуть стандартный режим:

sysctl -w vm.overcommit_memory=0

Или протестировать более либеральное поведение:

sysctl -w vm.overcommit_memory=1

vm.overcommit_memory не добавляет системе реальную память. Он лишь меняет политику допуска к резервированию. Если источник проблемы — runaway-процесс или неверный sizing, менять нужно именно их.

Постоянную настройку лучше выносить в отдельный файл в /etc/sysctl.d/ и применять только после понимания нагрузки и поведения приложений.

Просмотр логов ядра и настройка swap на сервере Linux

Когда виноват не RAM, а лимит на процессы

Если система не может делать fork, проверьте не только память, но и число процессов на пользователя, сервис и систему. Особенно это важно на серверах с CI-задачами, контейнерами, большим числом воркеров и плотным cron.

ulimit -u
cat /etc/security/limits.conf
grep -R nproc /etc/security/limits.d

Для systemd-сервисов полезно посмотреть:

systemctl show your-service -p TasksMax
systemctl cat your-service

Если сервис уткнулся в TasksMax, симптомы очень похожи на нехватку памяти: новые процессы не стартуют, SSH ведёт себя нестабильно, часть команд не выполняется. Но простое увеличение лимита без поиска причины часто только откладывает повторение проблемы.

Виртуальный хостинг FastFox
Виртуальный хостинг для сайтов
Универсальное решение для создания и размещения сайтов любой сложности в Интернете от 95₽ / мес

Частые источники memory exhaustion на практике

PHP-FPM

Очень частый источник аварий на веб-серверах. Неверно выбранный pm.max_children быстро съедает всю память. Оценивать пул нужно по реальному потреблению воркеров, а не по усреднённым советам.

MySQL и PostgreSQL

На маленьких серверах опасны завышенные буферы и параметры, которые умножаются на число соединений. Итог — память уходит в базу, а системе уже не хватает ресурсов на остальные процессы.

Docker-контейнеры без лимитов

Один runaway-процесс внутри контейнера легко уносит весь хост, если нет memory limits. Особенно неприятно, когда от этого перестаёт работать SSH.

Java и другие тяжёлые сервисы

Heap, кэши и фоновые потоки должны вписываться в общий memory budget сервера. Иначе приложение живёт на грани OOM даже при средней нагрузке.

Как предотвратить повторение инцидента

Добавьте swap

На небольшом сервере swap — это страховка, а не роскошь. Он не заменяет RAM, но помогает пережить краткие пики и сохранить доступ для аварийного входа.

Настройте мониторинг

Минимальный набор метрик: RAM, swap, число процессов, RSS по ключевым сервисам, события OOM killer, а также pressure по памяти. Без исторических графиков утечки памяти почти всегда замечают слишком поздно.

Ограничьте прожорливые сервисы

Используйте MemoryMax и TasksMax в systemd, memory limits в контейнерах, корректный размер пула в PHP-FPM, разумные настройки heap в Java. Задача — добиться контролируемой деградации, а не падения всего хоста.

Проверьте baseline sysctl

Если кто-то менял vm.overcommit_memory или vm.swappiness без понятной причины, лучше вернуться к адекватной базовой конфигурации и заново протестировать нагрузку.

Планируйте ресурсы заранее

Если проект стабильно растёт, полезно не только тушить инциденты, но и пересматривать capacity plan. Для небольших сайтов и типовых PHP-проектов часть проблем решается на правильно подобранном виртуальном хостинге, а для более требовательных сервисов — на выделенном профиле ресурсов. Если оптимизируете PHP на shared-среде, может пригодиться статья про настройку PHP, OPcache и Brotli на виртуальном хостинге.

Пошаговый чек-лист

  1. Не закрывайте текущую рабочую SSH-сессию.
  2. Проверьте free -h, swapon --show и показатели из /proc/meminfo.
  3. Посмотрите dmesg и journalctl -k -b на признаки OOM.
  4. Найдите процессы с максимальным RSS.
  5. Проверьте ulimit, число потоков и TasksMax.
  6. Остановите runaway-процесс или проблемный сервис.
  7. Если swap нет, добавьте временный swap-файл.
  8. После стабилизации зафиксируйте корневую причину и измените конфигурацию, а не только перезагрузите сервер.

Вывод

Ошибки fork cannot allocate memory, ssh cannot allocate memory и похожие сообщения почти всегда указывают на серьёзный перекос в ресурсах или лимитах. На Debian и Ubuntu корень обычно находится в одном из четырёх мест: реально закончилась память, отсутствует swap, неверно настроен overcommit или система уткнулась в лимиты процессов и cgroup.

Правильная последовательность действий такая: сначала сохранить доступ и вернуть управляемость, затем быстро найти виновника по логам и фактическому потреблению памяти, а после — исправить sizing, лимиты и мониторинг. Перезагрузка помогает ненадолго. Понимание причины помогает не ловить ту же аварию снова.

Поделиться статьей

Вам будет интересно

Debian/Ubuntu: sudo: unable to change expired password при входе по SSH — как исправить OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: sudo: unable to change expired password при входе по SSH — как исправить

Если в Debian или Ubuntu при входе по SSH или запуске sudo появляется unable to change expired password, проблема обычно связана н ...
Debian/Ubuntu: как исправить send-packets: Broken pipe и write failed в SSH, SCP, SFTP и rsync OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить send-packets: Broken pipe и write failed в SSH, SCP, SFTP и rsync

Если SSH-сессия внезапно рвётся с ошибками send-packets: Broken pipe, write failed или client_loop: send disconnect: Broken pipe, ...
Debian/Ubuntu: как исправить sshd re-exec requires execution with an absolute path OpenAI Статья написана AI (GPT 5)

Debian/Ubuntu: как исправить sshd re-exec requires execution with an absolute path

Если в Debian или Ubuntu команда systemctl restart ssh завершается ошибкой sshd re-exec requires execution with an absolute path, ...