OOM (Out of Memory) Crashes & RAM Limits

Performance & Lag Reviewed September 6, 2026 3 min read

A «Killed» status with no crash report, no stack trace and no warning is one of the more disorienting things a server owner sees — because unlike almost every other failure, this one is not the game software's fault, and the game software never gets a chance to say anything about it.

Why the kill is instant and silent

A container's memory limit is enforced by the operating system kernel, not by Java. When total memory use — Java's heap, plus everything Java allocates outside the heap, plus every other process in the container — crosses that limit, the kernel does not ask nicely. It sends a signal that terminates the process immediately, with no chance for Java to log an exception, write a crash report, or even flush its own output. One moment the server is running; the next, the process no longer exists.

This is also why swap is disabled by design rather than an oversight: swap would let a server exceeding its memory limit slow to a crawl instead of being killed, trading a fast, clean failure for a slow, degraded one that is often worse for every player connected at the time — and it would do that at the cost of the NVMe I/O performance the rest of the platform is built around.

What actually uses memory, beyond -Xmx

ConsumerCounts against the container limit?
The Java heap, up to -XmxYes — this is what the flag controls
Thread stacks (one per plugin thread, per connection handler)Yes, and not included in -Xmx
Direct/off-heap buffers (used heavily by Netty for networking)Yes, and not included in -Xmx
Memory-mapped region filesYes, though the kernel can reclaim this more readily under pressure
Any other process in the containerYes — a web map plugin, a bundled proxy, anything else running alongside
This is the single most common OOM cause: -Xmx set too close to the container limit

Setting -Xmx to the full memory allocation leaves nothing for everything on the table above. A server with a 4 GB plan and -Xmx4G is not using all 4 GB safely — it is guaranteeing an OOM kill the moment thread stacks and networking buffers need their share, which happens under ordinary load, not unusual load. Leaving 10–20% of the plan's memory unassigned to -Xmx is what actually uses the plan safely.

Diagnosing which kind of OOM this is

  1. Check whether it happens at a predictable time or grows worse over sessions

    A leak climbs steadily across a session and eventually kills regardless of headroom. A headroom problem kills at roughly the same memory level every time, often tied to peak player count.

  2. Watch the memory graph across a full session, not just at the crash

    A steady climb that never comes back down between quiet periods is the signature of a leak — usually a plugin holding references to entities, players or chunks it should be releasing.

  3. If it is headroom, lower -Xmx, not raise the plan first

    A crash from -Xmx set too high is a configuration problem a plan upgrade happens to mask rather than fix — worth ruling out before spending on more memory the same misconfiguration would eventually fill too.

How to confirm it worked

The server runs through a full busy session — the point where it previously died — with memory settling into the sawtooth pattern of normal garbage collection rather than climbing to the ceiling.