8 min read

Fix 'java.lang.OutOfMemoryError: Java heap space' in Minecraft

java.lang.outofmemoryerror java heap space on a Minecraft server means the heap outgrew -Xmx. Diagnose an undersized box vs a plugin leak, then fix it.

Fix 'java.lang.OutOfMemoryError: Java heap space' in Minecraft

java.lang.OutOfMemoryError: Java heap space means the live objects in your server's heap outgrew the -Xmx ceiling you handed the JVM, so it gave up rather than allocate memory it doesn't have. Raising -Xmx is the right fix only when the box was genuinely undersized. If the real driver is a plugin leak or runaway chunk-loading, a bigger ceiling just buys a slightly later crash and longer garbage-collection pauses on the way there.

First, read the error — and rule out the look-alikes

Open logs/latest.log and find the exact line. The word right after OutOfMemoryError: is your diagnosis, and three different problems get lumped under the same panic.

java.lang.OutOfMemoryError: GC overhead limit exceeded is the same root cause wearing a different hat. The heap is starved, and the JVM is now spending more than 98% of its time in GC to reclaim less than 2% of the heap, so it throws in the towel. Treat it exactly like a heap-space error.

java.lang.OutOfMemoryError: Metaspace is not the heap at all. Metaspace holds class metadata, and this one is almost always a classloader leak from repeated /reload confirm or a plugin that reloads its own classes. Adding -Xmx does nothing here. The fix is to stop /reload-ing, restart clean, and if it persists, raise -XX:MaxMetaspaceSize.

Then there's Killed with no Java stack trace anywhere. That is the operating system's out-of-memory killer stepping in because -Xmx was set larger than the machine actually has. It's the opposite problem: too much heap, not too little. If you see Killed and no crash report, jump straight to sizing.

Why cranking -Xmx blindly backfires

More RAM is usually the wrong first move, and here's the concrete why.

Set -Xmx bigger than the box and the OS OOM killer does exactly what I described above. The process vanishes with Killed and leaves no crash report, which is harder to diagnose than a clean heap error that at least prints a stack trace. PaperMC's rule of thumb is to keep -Xmx roughly 1000-1500MB below total RAM. On an 8GB machine that means about 6.5GB, not 8.

A bigger heap is also more territory for G1 to scan on every collection, so pauses get longer. You trade a clean OOM for Can't keep up! Is the server overloaded? in console, visible stutter, and longer stop-the-world freezes when a collection finally lands. That's a worse day than the crash you were trying to avoid.

And a leak fills any ceiling you give it. Moving from 4GB to 8GB doesn't stop a leak; it just moves the crash from roughly two hours out to roughly six. Worth saying plainly: high memory usage is not itself a leak. A JVM using all the RAM you gave it is normal and healthy. A leak is the post-GC floor climbing — the low point after each collection creeping upward until it hits the top.

One edge case worth a single line: past about 32GB the JVM drops compressed object pointers, so 33GB of heap can actually hold fewer objects than 31GB. Don't nudge just past 32GB.

Size the heap right for the actual box

If the box really was undersized, here's the legit version of "add RAM." Set -Xms equal to -Xmx so the JVM grabs the whole heap up front instead of resizing under load, and add -XX:+AlwaysPreTouch so those pages are actually committed at startup rather than faulted in mid-tick. The full launch string and the reasoning behind matching those two values live in the best Aikar JVM flags.

Aikar's floor is at least 6-10GB for a plugin server regardless of headcount. Under about 6GB, G1 collects almost constantly and you'll OOM under any real chunk load. Modded packs and Skyblock want far more than that baseline. Keep the 1000-1500MB headroom below total RAM no matter what number you land on. For picking an actual figure against player count, how much RAM a 20-player server needs walks through it.

Java 25 is the baseline for 26.x, since 26.1, 26.2 and 26.3 all require it. If you're running plugins, target the newest version Paper's downloads page marks as stable rather than one still behind its experimental toggle; a brand-new drop sits there for a while after release. The keys you're touching are -Xmx, -Xms, and -XX:+AlwaysPreTouch.

Catch a plugin or mod leak

If a correctly sized heap still climbs to the ceiling under ordinary load and never drops back down after a GC, that's a leak — not a size problem. A few ways to pin it.

Add -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./dumps to the launch flags. The next OOM will write an .hprof file you can open in a tool like Eclipse MAT, which sorts the heap by what's actually holding memory.

For a live look, install Spark and run /spark heapsummary for a by-class breakdown of what's on the heap right now. The tell is the post-GC floor: watch it over an hour, and a sawtooth that keeps climbing after every collection is a leak. A sawtooth that returns to the same floor each time is a healthy server doing its job.

The OOM stack trace in latest.log names whatever was allocating at the instant it ran out. Treat that as a hint, not proof — same caveat as reading a plugin name off a crash report. The thing that tipped it over isn't necessarily the thing that filled it. Why your server keeps crashing covers reading crash-reports/ and that plugin-name rule in more depth.

The fix is usually to update the offending plugin to a build matching your exact server version, or pull it entirely to confirm the climb stops. Leaks spike right after a server update, when a plugin compiled against the old version starts mishandling the new one. If you need to stay up while you hunt, a scheduled restart resets a slow leak on a timer — but that's a bandage, not a repair.

Stop runaway chunk-loading and entity pileups

Even a healthy, well-sized heap will OOM if the world asks it to hold too much at once. Two drivers do most of the damage.

Loaded chunks are the first. View-distance or simulation-distance set too high, players spread far apart across the map, no world border, no pregeneration, or a plugin force-loading chunks all multiply how much terrain sits in memory. Elytra flights and nether-portal chunk spam are the classic culprits — one player boosting across unloaded terrain can pull in chunks faster than they unload.

Entities are the second. Mob farms, dropped items that never despawn, and XP orbs stacking up all live on the heap.

Drop view-distance to 6-8 and simulation-distance to 4 in server.properties, or per-world in Paper. Set a world border with /worldborder set so the map can't sprawl forever. Pregenerate with Chunky so terrain is written to disk instead of being generated and held live. Then tighten entity caps and despawn ranges in config/paper-world-defaults.yml. For a broader pass at trimming the load itself, reduce your server's RAM usage collects these in one place. Skip the RAM-cleaner plugins — they fight the garbage collector and usually make pauses worse, not better.

The order to work through

Read the word after OutOfMemoryError: first, so you know which of the three problems you actually have. Rule out Killed (too much heap) and Metaspace (a classloader issue) before touching -Xmx. Confirm the heap size is sane for the box — -Xms equal to -Xmx, headroom left below total RAM — and only then, if it's right-sized and still climbing, hunt the leak with Spark or a heap dump and cut the load from chunks and entities. Reach for a restart schedule last, as a stopgap while you fix the real thing.

FAQ

Is 4GB enough to stop this error?

No. Aikar's floor is around 6GB even for a handful of players, and below that G1 collects almost constantly and you'll OOM under any real chunk load. Going from 4GB to 6-8GB is a legitimate fix if the box was genuinely undersized. But if you're already at 10GB or more and still throwing the error, stop adding RAM — that's a leak, not a size problem.

Does -Xmx cover the whole Java process's memory?

No, and this trips people up. Metaspace, thread stacks, direct and off-heap byte buffers, and the GC's own bookkeeping structures all live outside -Xmx and can add a gigabyte or more on top. That's exactly why the 1000-1500MB headroom rule exists, and why top or htop shows the process using noticeably more memory than your -Xmx number.

Will -XX:+DisableExplicitGC or a clear-lag plugin fix it?

No to both. -XX:+DisableExplicitGC only makes the JVM ignore System.gc() calls, which prevents forced pauses but adds exactly zero memory. RAM-cleaner and clear-lag plugins fight the garbage collector on its own turf and usually make pauses worse. The only thing that clears a real leak's accumulated objects is a full process restart.

Why did OOM start right after I updated to 26.3?

A plugin compiled against 26.2 and loaded on 26.3 can leak or over-allocate because it's mishandling changed internals, and that's likelier still if your Paper build for 26.3 is one of the experimental ones. Before you assume the heap is too small, roll back to the stable target from the backup you took before updating, and check the live 26.2 and 26.1 rankings to see what plugin servers are still running. Wait for the plugin to ship a real 26.3 build, then retest before touching -Xmx.