Common Java OutOfMemoryError Types and Their Solutions
This article explains the various OutOfMemoryError variants in the Java Virtual Machine, illustrates each with reproducible code examples, analyzes root causes, and provides practical mitigation strategies such as JVM flags, code refactoring, and system‑level adjustments.
1. StackOverflowError
The JVM stack has a limited depth; recursive calls without a termination condition eventually exhaust the stack and throw java.lang.StackOverflowError.
1.1 Example
public class StackOverflowErrorDemo {
public static void main(String[] args) {
javaKeeper();
}
private static void javaKeeper() {
javaKeeper();
}
}Running this program produces:
Exception in thread "main" java.lang.StackOverflowError
at oom.StackOverflowErrorDemo.javaKeeper(StackOverflowErrorDemo.java:15)1.2 Causes
Infinite recursion (most common).
Executing a huge number of methods causing stack exhaustion.
Declaring massive local variables.
Native code that allocates large buffers on the stack (e.g., java.net.SocketInputStream.read0).
1.3 Solutions
Fix the recursive logic and remove infinite calls.
Check for circular class dependencies that may trigger recursion via toString().
Increase thread stack size with the JVM option -Xss when necessary.
2. Java Heap Space
The Java heap stores object instances. Continuously creating objects until the heap reaches its maximum size triggers java.lang.OutOfMemoryError: Java heap space, the most common OOM in real applications.
2.1 Example
/**
* JVM parameter: -Xmx12m
*/
public class JavaHeapSpaceDemo {
static final int SIZE = 2 * 1024 * 1024;
public static void main(String[] a) {
int[] i = new int[SIZE];
}
}Running with -Xmx12m results in:
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at oom.JavaHeapSpaceDemo.main(JavaHeapSpaceDemo.java:13)2.2 Causes
Attempting to allocate an excessively large object (e.g., a huge array).
Unexpected traffic spikes causing massive object creation.
Overuse of finalizers preventing timely GC.
Memory leaks where object references are never released (e.g., unclosed File resources).
2.3 Solutions
Usually increasing the heap size with -Xmx solves the problem. If the issue persists:
Validate the necessity of large objects; limit result set sizes.
Apply rate‑limiting or degrade service under high load.
Detect and fix memory leaks by releasing resources properly.
3. GC Overhead Limit Exceeded
When the JVM spends more than 98% of its time performing GC and recovers less than 2% of heap memory for five consecutive cycles, it throws java.lang.OutOfMemoryError: GC overhead limit exceeded, indicating the application has almost exhausted all usable memory.
3.1 Example
/**
* JVM parameters: -Xmx14m -XX:+PrintGCDetails
*/
public class KeylessEntry {
static class Key {
Integer id;
Key(Integer id) { this.id = id; }
@Override public int hashCode() { return id.hashCode(); }
}
public static void main(String[] args) {
Map m = new HashMap();
while (true) {
for (int i = 0; i < 1000; i++) {
if (!m.containsKey(new Key(i))) {
m.put(new Key(i), "Number:" + i);
}
}
System.out.println("m.size()=" + m.size());
}
}
}Output shows the map growing beyond the intended limit and eventually:
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceededThe problem stems from overriding hashCode() without overriding equals(), causing containsKey() to fail and the map to grow indefinitely.
3.2 Solutions
Disable the limit (not recommended) with -XX:-UseGCOverheadLimit.
Identify and eliminate infinite loops or memory‑intensive code.
Perform heap dumps and analyze for leaks before simply increasing memory.
4. Direct Buffer Memory
Using NIO's ByteBuffer.allocateDirect allocates off‑heap (native) memory. If native memory is exhausted, the JVM throws java.lang.OutOfMemoryError: Direct buffer memory.
4.1 Example
/**
* VM Options: -Xms10m,-Xmx10m,-XX:+PrintGCDetails -XX:MaxDirectMemorySize=5m
*/
public class DirectBufferMemoryDemo {
public static void main(String[] args) {
System.out.println("maxDirectMemory is:" + sun.misc.VM.maxDirectMemory() / 1024 / 1024 + "MB");
//ByteBuffer buffer = ByteBuffer.allocate(6*1024*1024);
ByteBuffer buffer = ByteBuffer.allocateDirect(6*1024*1024);
}
}Running with -XX:MaxDirectMemorySize=5m yields:
maxDirectMemory is:5MB
Exception in thread "main" java.lang.OutOfMemoryError: Direct buffer memory4.2 Solutions
Use ByteBuffer.allocateDirect sparingly; monitor with tools like Arthas.
Check for indirect NIO usage (Netty, Jetty, etc.).
Adjust the limit via -XX:MaxDirectMemorySize.
Remove -XX:+DisableExplicitGC if present, so System.gc() can reclaim direct buffers.
Manually clean buffers via sun.misc.Cleaner.clean() when appropriate.
Upgrade hardware if native memory truly runs out.
5. Unable to Create New Native Thread
Each Java thread maps to a native OS thread. When the OS cannot allocate the required native memory or thread count limit is reached, the JVM throws java.lang.OutOfMemoryError: unable to create new native thread .
5.1 Example
public static void main(String[] args) {
while (true) {
new Thread(() -> {
try { Thread.sleep(Integer.MAX_VALUE); } catch (InterruptedException e) {}
}).start();
}
}Result:
Error occurred during initialization of VM
java.lang.OutOfMemoryError: unable to create new native thread5.2 Causes
Exceeding the OS‑level maximum thread count.
Reaching kernel.pid_max (requires reboot).
Insufficient native memory (e.g., 32‑bit address space limits).
5.3 Solutions
Reduce the number of threads; use thread pools.
Increase OS limits with ulimit -u or equivalent.
6. Metaspace
Since Java 8, the permanent generation (PermGen) was replaced by Metaspace, which resides in native memory. Exhausting Metaspace results in java.lang.OutOfMemoryError: Metaspace .
6.1 Example
/**
* JVM Options: -XX:MetaspaceSize=10m -XX:MaxMetaspaceSize=10m
*/
public class MetaspaceOOMDemo {
public static void main(String[] args) {
while (true) {
Enhancer enhancer = new Enhancer();
enhancer.setSuperclass(MetaspaceOOMDemo.class);
enhancer.setUseCache(false);
enhancer.setCallback((MethodInterceptor) (o, method, objects, methodProxy) -> {
return methodProxy.invokeSuper(o, objects);
});
enhancer.create();
}
}
}Result:
org.springframework.cglib.core.CodeGenerationException: java.lang.OutOfMemoryError-->Metaspace6.2 Solutions
Limit Metaspace size with -XX:MaxMetaspaceSize.
Set initial size via -XX:MetaspaceSize to trigger timely GC of class metadata.
Adjust free‑ratio parameters ( -XX:MinMetaspaceFreeRatio, -XX:MaxMetaspaceFreeRatio) to control reclamation frequency.
7. Requested Array Size Exceeds VM Limit
7.1 Example
public static void main(String[] args) {
int[] arr = new int[Integer.MAX_VALUE];
}Result:
Exception in thread "main" java.lang.OutOfMemoryError: Requested array size exceeds VM limitThe JVM caps the maximum array length (approximately Integer.MAX_VALUE-2 ). Creating larger arrays requires redesigning the data structure.
8. Out of Swap Space
When the total memory requested by the JVM exceeds physical memory, the OS starts swapping. If swap space is also exhausted, the JVM throws java.lang.OutOfMemoryError: Out of swap space .
9. Kill Process or Sacrifice Child
Linux’s OOM Killer may terminate processes when the system runs out of memory. The JVM may surface this as Kill process or sacrifice child , which originates from the OS rather than the JVM.
9.1 Causes
Processes consuming excessive memory, causing the kernel to invoke the OOM Killer.
Over‑commit settings allowing allocation beyond physical limits.
9.2 Solutions
Upgrade server resources or isolate workloads.
Tune the OOM Killer parameters to protect critical processes.
References: "深入理解 Java 虚拟机 第 3 版", plumbr.io, Alibaba Cloud articles, and the StabilityGuide GitHub repository.
Signed-in readers can open the original source through BestHub's protected redirect.
This article has been distilled and summarized from source material, then republished for learning and reference. If you believe it infringes your rights, please contactand we will review it promptly.
Full-Stack Internet Architecture
Introducing full-stack Internet architecture technologies centered on Java
How this landed with the community
Was this worth your time?
0 Comments
Thoughtful readers leave field notes, pushback, and hard-won operational detail here.
