java.lang.OutOfMemoryError: Java heap space
Fixing Java OutOfMemoryError: Java heap space
This error occurs when the JVM cannot allocate more objects in the heap. Increase heap size with -Xmx or optimize memory usage to resolve it.
Symptoms
The application throws java.lang.OutOfMemoryError: Java heap space and may crash or become unresponsive. This typically occurs during object creation, data processing, or after prolonged runtime. The error may appear in logs or console output.
Root Causes
- Insufficient heap size: The default JVM heap (often 256MB on 32-bit or 1GB on 64-bit) is too small for the workload.
- Memory leak: Objects are unintentionally retained (e.g., forgotten references, static collections, unclosed resources) causing heap exhaustion.
- Large data sets: Processing large files, database results, or in-memory caches without proper batching.
- Incorrect JVM configuration: Using
-Xmsand-Xmxvalues that are too low or mismatched. - Fragmentation: Although rare in modern JVMs, frequent allocation of many small objects can fragment the heap.
Step-by-step Fix
- Increase heap size: Add JVM arguments
-Xms512m -Xmx2g(adjust values as needed). For example:java -Xms512m -Xmx2g -jar myapp.jar - Enable GC logging: Use
-XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:gc.logto monitor garbage collection behavior. - Generate a heap dump: Add
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprofto capture memory state on crash. - Analyze heap dump: Use tools like Eclipse MAT, VisualVM, or JProfiler to find memory leaks. Look for large object graphs, excessive instances, or retained memory.
- Fix memory leaks: Nullify unused references, close resources (streams, connections), use weak references for caches, and avoid static collections that grow indefinitely.
- Optimize code: Process data in batches, use streaming APIs (e.g., Java Streams with
limit()), and avoid loading entire datasets into memory. - Adjust GC settings: Consider
-XX:+UseG1GCfor large heaps, or-XX:MaxGCPauseMillis=200to tune pause times.
Alternative Fixes
- Reduce object size: Use primitive types instead of wrappers, avoid unnecessary object creation.
- Increase heap gradually: If the application runs in a container, ensure container memory limits align with JVM heap (use
-XX:+UseContainerSupporton Java 8u191+). - Use off-heap storage: For large caches, consider using memory-mapped files or direct ByteBuffers.
- Upgrade JVM: Newer JVMs have better garbage collectors and memory management (e.g., ZGC in Java 11+).
Prevention
- Monitor memory usage: Set up alerts on heap usage via JMX or APM tools.
- Perform load testing: Simulate production traffic to identify memory issues before deployment.
- Code reviews: Check for common memory leak patterns (e.g., listeners, inner classes, thread locals).
- Use memory profiling: Regularly profile the application in staging to catch regressions.
- Set appropriate defaults: Configure
-Xmsequal to-Xmxto avoid resizing overhead.
Example Configuration
| Parameter | Value | Description |
|---|---|---|
| -Xms | 1g | Initial heap size |
| -Xmx | 4g | Maximum heap size |
| -XX:+UseG1GC | enabled | Use G1 garbage collector |
| -XX:MaxGCPauseMillis | 200 | Target GC pause time |
| -XX:+HeapDumpOnOutOfMemoryError | enabled | Auto dump on OOM |
By following these steps, you can resolve the Java heap space error and build more robust applications.
Was this solution helpful?