The process terminated due to memory, although free RAM remained on the VPS
Free server memory does not rule out limits on a specific process group. We examine local OOM, the meaning of cgroup v2 counters, and the data needed before changing your tariff.

In this article
Импорт каталога прервался, приложение запустилось заново, а на графике VPS ещё несколько свободных гигабайт. Эти наблюдения могут быть совместимы. Linux ограничивает память не только для всей машины: у группы процессов бывает собственный предел. Покупка дополнительной RAM не устранит такой предел автоматически.
Главный вопрос — на каком уровне закончился разрешённый ресурс. Отдельно проверяют память машины, ограничения группы и правила самого приложения. В этом разборе речь о Linux с cgroup v2. Здесь нет команд изменения лимитов или воспроизведения аварии: задача — правильно прочитать свидетельства уже произошедшего события.
Три границы одной задачи
Представим учебную конфигурацию. У VPS 16 ГиБ RAM, панель показывает около 6 ГиБ доступной памяти, а службе импорта назначен предел группы 1 ГиБ. Это три разных числа. Первое описывает размер машины, второе — оценку на уровне ОС, третье — ограничение конкретной нагрузки. Свободное место за пределами разрешённого бюджета группы само по себе не делает её бюджет больше.
Группа может объединять несколько рабочих процессов. Если каждый из четырёх обработчиков выглядит небольшим, суммарное потребление группы всё равно способно приблизиться к её ограничению. Кроме того, учитывается не одна только величина, которую приложение называет своей памятью. Поэтому сравнение одной строки процесса с общим графиком часто пропускает нужный уровень.
Есть и ограничения внутри приложения. Например, ошибка о достижении собственного бюджета памяти ещё не доказывает вмешательство ядра. Программа могла сама остановить операцию. Нужны исходное сообщение, время и сведения о завершении процесса: пересказ «серверу не хватило памяти» стирает важное различие.

Что именно подтверждает счётчик
В cgroup v2 параметр memory.max задаёт жёсткую границу памяти группы. Когда потребление достигает её и не удаётся освободить достаточно памяти, ядро может вызвать OOM killer внутри группы — механизм завершения процессов при нехватке памяти. Ограничения и события рассматривают в иерархии групп: родительская граница также может оказаться определяющей.
У memory.high другая роль: превышение связано с торможением задач и усиленным освобождением памяти. Само по себе превышение этой границы не вызывает OOM killer. Поэтому задержки и аварийное завершение нельзя объяснять одним названием «лимит памяти» без уточнения параметра.
В наборе событий памяти cgroup v2 есть отдельные счётчики high, max, oom и oom_kill. Последний считает процессы группы, завершённые OOM killer. Положительное значение подтверждает такие события за время жизни соответствующего счётчика, но не сообщает, что последнее завершение приложения произошло именно сейчас и именно по этой причине.
Полезны два наблюдения с известным временем. В учебном примере до импорта oom_kill равен 2, после — 3. Прирост равен одному. Он становится предметным свидетельством, если проверена та же группа и журнал связывает событие с нужным процессом. Одно позднее значение 3 без исходного снимка такой связи не устанавливает.
Основной набор счётчиков событий учитывает и события потомков. Для событий самой группы предусмотрен отдельный локальный набор. Если администратор прочитал счётчик родительской группы, вывод может относиться к другой дочерней нагрузке. После пересоздания контейнера или группы прежние и новые числа также нельзя бесконтрольно вычитать друг из друга.
Почему после сбоя память выглядит свободной
Завершённый процесс освобождает ресурсы. График, снятый после аварии, уже описывает другое состояние. Редкая запись метрик может пропустить короткий пик. Поэтому спокойный график через минуту после остановки не опровергает событие за предыдущий интервал.
Обратная ошибка — считать любое внезапное завершение доказанным OOM. Процесс могли остановить по другой причине. Само сообщение о принудительной остановке не устанавливает, кто её инициировал. Для диагноза требуется сообщение ядра, данные среды управления или другое свидетельство OOM, относящееся к тому же эпизоду.
Точно так же нужно различать доступную память хоста и сведения, видимые внутри контейнера. Интерфейс мониторинга может показывать ресурс всей машины, лимит контейнера либо собственную расчётную величину. До сравнения чисел выясните источник каждого графика, единицы и шаг измерения.
Какие данные передать администратору
Время сбоя с часовым поясом, название операции и точное сообщение приложения без данных покупателей.
Идентификатор нагрузки и группы, её действующие ограничения, ограничения родителей и время создания текущего экземпляра.
Изменение соответствующих счётчиков в интервале, сведения о завершении процесса и относящиеся к нему сообщения ядра.
Динамику потребления группы и машины, число одновременных обработчиков и изменения режима импорта.
Сбор этих сведений не требует предварительно снимать ограничения. Если чтение недоступно из контейнера, запрос направляют администратору хоста штатным способом. Отсутствие доступа нельзя записывать в отчёт как отсутствие события.
После подтверждения локальной границы появится несколько вариантов дальнейшего исследования: уменьшить одновременную обработку, проверить размер порций, найти рост потребления или обосновать другой бюджет. Каждый вариант меняет работу системы и требует отдельной проверки. Если приложение само ограничило память, вмешательство понадобится на другом уровне.
Полезный результат разбора звучит конкретно: во время такого-то импорта в такой-то группе появился новый факт OOM, а общий ресурс VPS оставался доступен. Или факт OOM подтвердить не удалось. Оба ответа помогают выбрать следующий шаг; фраза «добавим памяти на всякий случай» нужный уровень ограничения не называет.
The catalog import stopped, the application restarted, yet the VPS graph still shows several free gigabytes. These observations can be consistent. Linux limits memory not only for the entire machine: a process group can have its own limit. Purchasing additional RAM does not automatically remove such a limit.
The main question is at which level the allowed resource was exhausted. Memory is checked separately at the machine level, the group level, and the application rules level. This analysis covers Linux with cgroup v2. There are no commands here to change limits or reproduce the crash: the task is to correctly interpret the evidence of an event that has already occurred.
Three boundaries of a single task
Consider a test configuration. The VPS has 16 GiB of RAM, the panel shows about 6 GiB of available memory, and the import service is assigned a group limit of 1 GiB. These are three different numbers. The first describes the machine size, the second is an OS-level estimate, and the third is a limit for a specific workload. Free space outside the group's allowed budget does not, by itself, increase that budget.
A group can encompass multiple workflows. Even if each of the four handlers appears small, the group's total consumption can still approach its limit. Moreover, the metric considered is not just the memory size the application reports as its own. Therefore, comparing a single process line against the overall graph often misses the relevant threshold.
There are also limits within the application itself. For example, an error indicating that a memory budget has been reached does not prove kernel intervention. The program might have stopped the operation on its own. The original message, timestamp, and process termination details are required: paraphrasing this as "the server ran out of memory" obscures a critical distinction.

What exactly the counter confirms
In cgroup v2, the memory.max parameter sets a hard memory limit for the group. When consumption reaches this limit and sufficient memory cannot be freed, the kernel may trigger the OOM killer within the group—a mechanism for terminating processes due to memory shortage. Limits and events are evaluated within the group hierarchy: the parent limit can also be decisive.
memory.high serves a different role: exceeding it is associated with task throttling and intensified memory reclamation. Exceeding this limit alone does not trigger the OOM killer. Therefore, delays and abrupt terminations cannot be explained solely by the term "memory limit" without specifying the parameter.
The cgroup v2 memory event set includes separate counters high, max, oom, and oom_kill. The last one counts processes in the group terminated by the OOM killer. A positive value confirms such events during the lifetime of the corresponding counter, but it does not indicate that the application was terminated exactly now and for exactly this reason.
Two observations with known timing are useful. In the tutorial example, oom_kill equals 2 before the import and 3 after. The increase is one. It becomes concrete evidence if the same group is verified and the log links the event to the correct process. A single later value of 3 without the initial snapshot does not establish such a link.
The main set of event counters includes events from child processes. For events of the group itself, a separate local set is provided. If an administrator reads a counter from the parent group, the output may refer to a different child load. After recreating a container or group, old and new values cannot be subtracted from each other without control.
Why Memory Appears Free After a Failure
A terminated process releases resources. A graph captured after the crash already describes a different state. Rare metric recording can miss a short spike. Therefore, a calm graph one minute after the stop does not refute an event from the previous interval.
The reverse error is to assume any sudden termination proves an OOM. The process might have been stopped for another reason. The forced termination message itself does not establish who initiated it. A diagnosis requires a kernel message, container management environment data, or other OOM evidence related to the same incident.
Similarly, you must distinguish between the host's available memory and what is visible inside the container. The monitoring interface may show the machine's total resource, the container's limit, or its own calculated value. Before comparing numbers, determine the source of each graph, the units, and the measurement step.
What Data to Provide to the Administrator
Failure time with time zone, operation name, and the exact application message without customer data.
Load and group identifiers, their current limits, parent limits, and the creation time of the current instance.
Changes in relevant counters over the interval, process termination details, and associated kernel messages.
Consumption dynamics for the group and machine, the number of simultaneous handlers, and changes in import mode.
Collecting this information does not require removing limits beforehand. If reading is unavailable from within the container, the request is sent to the host administrator via standard procedures. Lack of access must not be recorded in the report as a lack of an event.
After confirming the local boundary, several options for further investigation appear: reduce concurrent processing, check portion sizes, identify consumption growth, or justify a different budget. Each option changes system behavior and requires separate verification. If the application itself limited memory, intervention will be needed at another level.
A useful analysis result is specific: during a specific import in a specific group, a new OOM event occurred, while the overall VPS resource remained available. Or the OOM event could not be confirmed. Both answers help choose the next step; the phrase 'add memory just in case' does not specify the required level of restriction.





Discussion 0
Share your experience and ask questions. Comments without links appear after editorial review.
No comments yet. Start the discussion.