Из-за временных ограничений на территории РФ наблюдаются проблемы с оплатой. Если платёж не проходит, оставьте запрос в службу поддержки.Служба поддержки работает 24/7 — мы всегда на связи по вопросам хостинга и серверов.Открыт прием заявок на аренду выделенных серверов и размещение оборудования в дата-центре.Напоминаем: рекомендуем включить резервное копирование для дополнительной защиты данных.Доступна новая линейка VPS/VDS с NVMe-дисками и увеличенной производительностью.Технические работы на части серверов завершены. Все сервисы работают в штатном режиме.
Статья5 мин чтенияПросмотры0

Процесс внезапно завершился: как подтвердить OOM в Ubuntu 24.04

Проверяем журнал ядра, systemd-oomd и лимит cgroup, чтобы отличить нехватку памяти от похожего сбоя и сохранить факты до изменений.

Комментарии 0

Стойка сервера с заполненным стеком модулей памяти и одним выпавшим модулем как метафора OOM
В этой статье

Процесс пропал, служба перезапустилась, а в приложении осталась только запись о неожиданном завершении. Это похоже на нехватку памяти, но по одному признаку выводить рано: тот же внешний симптом дают ручной SIGKILL, лимит контейнера, решение systemd-oomd и сбой самого приложения.

Главный ориентир: OOM подтверждает не слово «killed», а связка времени, сообщения механизма завершения и контекста памяти. Сначала проверим журнал ядра, затем отдельно systemd-oomd и cgroup. Только после этого есть смысл обсуждать лимит, нагрузку или утечку.

Границы инструкции

Команды рассчитаны на Ubuntu 24.04 LTS с systemd 255 и cgroup v2. Они читают состояние и журналы, не перезапускают службы и не меняют лимиты. Синтаксис journalctl и systemctl выполнен 29 сентября 2026 года в изолированной среде Ubuntu 24.04.3 LTS; в ней не было сохранённых журналов и события OOM. Утилита oomctl на стенде отсутствовала, поэтому её команда сверена с руководством Ubuntu для systemd 255, но фактически не выполнялась. Намеренно вызывать OOM ради проверки на рабочем сервере не нужно.

1. Зафиксируйте загрузку и время события

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

journalctl --list-boots --no-pager

Номер 0 обычно относится к текущей загрузке, -1 — к предыдущей. Отсутствие предыдущей загрузки в списке не доказывает, что события не было: журнал мог храниться только в памяти, быть ротирован или находиться на стороне хоста. Запишите часовой пояс и узкий интервал вокруг сбоя, например десять минут.

2. Проверьте сообщения OOM ядра

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

journalctl -k -b 0 --since "2026-09-29 02:10:00" --until "2026-09-29 02:20:00" --grep='oom-kill|Out of memory|Killed process' --no-pager

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

  • oom-kill: помогает увидеть контекст события: нехватку на всём узле либо ограничение внутри cgroup.

  • Killed process указывает выбранный процесс и снимок его памяти в момент решения, но не доказывает, что именно он создал первопричину.

  • Упоминание cgroup или memcg связывает событие с локальным лимитом. Свободная память вне этой группы могла ещё оставаться.

Схема различий между OOM ядра и systemd-oomd при одинаковом симптоме завершения процесса
Одинаковый симптом требует проверки двух журналов: ядра и systemd-oomd.

3. Отделите systemd-oomd от OOM ядра

В Ubuntu процесс может быть завершён и пользователем пространства systemd-oomd. Он следит за давлением памяти в cgroup v2 и действует до классического глобального OOM ядра. Поэтому его журнал проверяют отдельно.

systemctl is-active systemd-oomd

journalctl -u systemd-oomd -b 0 --since "2026-09-29 02:10:00" --until "2026-09-29 02:20:00" --no-pager

Если служба активна, её запись о выбранной cgroup и времени — прямое направление для проверки. Текущий снимок наблюдаемых групп можно запросить отдельно, когда установлен пакет с oomctl.

oomctl --no-pager dump

Вывод oomctl показывает текущее состояние, а не восстанавливает историю уже произошедшего события. Неактивный или отсутствующий systemd-oomd также ничего не говорит о решениях OOM ядра.

4. Свяжите событие со службой и лимитом cgroup

Для службы приложения соберите её текущее состояние и параметры памяти. Вместо example.service подставьте реальное имя юнита.

systemctl show example.service -p ActiveState -p Result -p ExecMainCode -p ExecMainStatus -p OOMPolicy -p ControlGroup -p MemoryCurrent -p MemoryPeak -p MemoryMax

Значение Result полезно, но не исчерпывает картину: рабочий процесс мог быть завершён, а мастер остаться активным. Поля MemoryCurrent и MemoryPeak после перезапуска описывают уже новый период и не являются доказательством прошлого пика. MemoryMax нужно сопоставлять с cgroup, указанной в ControlGroup.

Если используется cgroup v2, дополнительные счётчики OOM относятся к конкретной группе. Сначала получите ControlGroup из предыдущей команды и проверьте её счётчики штатными средствами вашей среды: не угадывайте каталог службы и не ослабляйте права доступа ради чтения.

Поля oom и oom_kill показывают накопленные события для этой cgroup, а oom_group_kill — групповые завершения, если они учитываются ядром. У счётчиков нет времени события; после пересоздания cgroup они могут начать новый период. Надёжнее сравнивать сохранённые снимки с журналом и мониторингом.

Схема локального OOM в cgroup при наличии свободной памяти на сервере
Локальный лимит cgroup может закончиться раньше общей памяти узла.

5. Если подтверждения нет

Пустой результат не превращает гипотезу в опровержение. Проверьте журнал приложения и контейнерного рантайма, консоль или события провайдера, сохранность journald и правильную загрузку. Код завершения, связанный с SIGKILL, сам по себе не называет инициатора: это мог быть OOM-механизм, администратор или оркестратор.

Сопоставляйте один и тот же интервал с доступной памятью, активностью swap, давлением PSI, лимитом cgroup и числом параллельных задач. График после перезапуска не восстанавливает состояние до сбоя, а свободная RAM на узле не исключает локальный лимит контейнера или службы.

Когда остановиться

  • Журнал недоступен, а событие уже прошло: сначала сохраните доступные факты и запросите данные у владельца хоста.

  • OOM повторяется, но неизвестно, какие процессы можно ограничивать или перезапускать.

  • Для продолжения нужно менять MemoryMax, swap, параметры ядра или политику systemd-oomd.

  • Сбой затрагивает базу данных, очередь заказов или другой сервис, где принудительный перезапуск может ухудшить восстановление.

Подтверждённый OOM отвечает на вопрос, кто и в каком контексте завершил процесс. Он ещё не доказывает утечку памяти и не обещает, что добавление RAM решит проблему. Сохраните время, строки журнала, cgroup, лимит и наблюдаемую нагрузку; изменение выбирают уже по этой связке, с резервной копией и планом отката там, где оно затрагивает данные или доступность.

Обсуждение 0

Делись опытом и задавай вопросы. Комментарии без ссылок появляются после проверки редактором.

Пока никто не написал. Начни обсуждение.