Symptoms
When a Java application throws java.lang.OutOfMemoryError: Java heap space, you may observe the following:
- Application crashes or freezes unexpectedly.
- Error logs contain the OutOfMemoryError stack trace.
- High CPU usage due to frequent garbage collection (GC) attempts.
- Response times degrade severely before the crash.
- In web applications, HTTP 500 errors or connection timeouts.
Root Causes
The error indicates the JVM cannot allocate more objects in the heap. Common causes include:
- Insufficient heap size: The default heap is too small for the application's memory requirements.
- Memory leak: Objects are unintentionally retained (e.g., in static collections, listeners, or caches) preventing garbage collection.
- Large data processing: Loading huge datasets (files, databases) into memory at once.
- Improper configuration: Incorrect
-Xmxor-XmsJVM arguments. - Fragmentation: Heap fragmentation can prevent allocation of large contiguous blocks.
Step-by-Step Fix
Step 1: Increase Heap Size Temporarily
Add JVM arguments to increase the maximum heap size. For example:
java -Xms512m -Xmx2g -jar myapp.jar-Xmssets initial heap size.-Xmxsets maximum heap size.
Adjust values based on available system memory. For production, set -Xms equal to -Xmx to avoid resizing overhead.
Step 2: Capture a Heap Dump
To analyze memory usage, generate a heap dump when the error occurs:
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof -jar myapp.jarAlternatively, use jmap on a running process:
jmap -dump:live,format=b,file=dump.hprof <pid>Step 3: Analyze the Heap Dump
Use tools like Eclipse Memory Analyzer (MAT) or VisualVM:
- Open the
.hproffile in MAT. - Look for the Leak Suspects report to identify large objects or retention paths.
- Check for objects with unexpected sizes or counts (e.g., millions of strings, unclosed connections).
- Examine GC roots to find why objects are not being collected.
Step 4: Fix Memory Leaks
Common fixes include:
- Clear static collections or use weak references (
WeakHashMap,WeakReference). - Close resources (streams, connections) in
finallyblocks or use try-with-resources. - Remove unused listeners or callbacks.
- Limit cache sizes with LRU eviction policies.
Step 5: Optimize Code
- Process data in streams instead of loading everything into memory.
- Use primitive types instead of wrapper objects where possible.
- Avoid creating unnecessary objects in loops.
Alternative Fixes
- Use G1GC: Garbage First Garbage Collector is often better for large heaps:
-XX:+UseG1GC. - Reduce object size: Use
-XX:+UseCompressedOops(enabled by default in many JVMs) to compress object pointers. - Increase Metaspace: If the error is about class metadata, increase
-XX:MaxMetaspaceSize. - Upgrade hardware: Add more RAM to the server.
Prevention
- Monitor memory: Use JMX, JConsole, or APM tools to track heap usage over time.
- Set appropriate heap sizes: Base
-Xmxon peak usage plus headroom (e.g., 20-30% overhead). - Perform load testing: Simulate production traffic to identify memory issues before deployment.
- Enable GC logging:
-Xlog:gc*(Java 9+) to detect frequent GCs or long pauses. - Code reviews: Look for potential memory leaks (e.g., unclosed resources, static collections).
By following these steps, you can resolve the Java heap space error and ensure your application runs reliably.