java.lang.OutOfMemoryError: Java heap space
Fix Java OutOfMemoryError: Java heap space
Java throws OutOfMemoryError when the heap is exhausted. Increase heap size with -Xmx or optimize memory usage to resolve.
Symptoms
- Application crashes with the error:
java.lang.OutOfMemoryError: Java heap space - Performance degradation or unresponsive application before crash
- Logs show repeated garbage collection (GC) overhead limit exceeded
- Unable to allocate new objects, especially in memory-intensive operations
Root Causes
- Insufficient heap size: Default JVM heap is often too small for production workloads (e.g., 64MB on some systems).
- Memory leaks: Objects are unintentionally held by strong references (e.g., static collections, listeners, caches).
- Excessive data loading: Loading large files, databases, or creating many objects without batching.
- Misconfigured JVM options: Missing or incorrect
-Xmxand-Xmsflags. - Fragmentation: Frequent allocation and deallocation of large objects leads to heap fragmentation.
Step-by-Step Fix
1. Increase Heap Size
Set the maximum heap size using JVM arguments. For example, to allocate 4GB:
java -Xms512m -Xmx4g -jar myapp.jar
-Xms: Initial heap size (e.g., 512m).-Xmx: Maximum heap size (e.g., 4g).- Do not exceed physical RAM; leave memory for OS and other processes.
2. Generate and Analyze Heap Dump
Add the following JVM options to capture a heap dump on OOM:
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=/path/to/dump.hprof
Use tools like Eclipse MAT or jvisualvm to open the .hprof file and identify the largest objects and suspect references.
3. Fix Memory Leaks
- Review static collections (e.g.,
HashMap) for unbounded growth. - Ensure listeners and callbacks are deregistered when no longer needed.
- Use weak references (
WeakHashMap,WeakReference) for caches. - Close resources (streams, connections) in
finallyblocks or use try-with-resources.
4. Optimize Code and Data Structures
- Use primitive types instead of wrapper classes where possible.
- Stream large files instead of loading them entirely into memory.
- Paginate database queries instead of fetching all rows at once.
- Reuse objects and avoid creating many short-lived objects in loops.
5. Tune Garbage Collection
Choose the right GC algorithm based on application needs:
| GC Type | JVM Flag | Use Case |
|---|---|---|
| G1GC | -XX:+UseG1GC | Low pause times, large heaps |
| Parallel GC | -XX:+UseParallelGC | High throughput, batch jobs |
| ZGC | -XX:+UseZGC | Very low latency, huge heaps |
Adjust young generation size with -Xmn to reduce promotion failures.
Alternative Fixes
- Use -XX:+UseContainerSupport (Java 10+) to respect container memory limits in Docker/Kubernetes.
- Reduce thread stack size with
-Xss256kif many threads are created. - Enable GC logging with
-Xlog:gc*to monitor heap usage patterns. - Switch to a different runtime (e.g., GraalVM native image) if heap is not the bottleneck.
Prevention
- Set realistic
-Xmxbased on load testing and monitoring. - Use memory profiling during development (e.g., JProfiler, YourKit).
- Implement circuit breakers or backpressure to prevent memory spikes.
- Regularly review heap dumps in staging environments.
- Automate memory leak detection with CI/CD pipeline tools.
By following these steps, you can resolve the OutOfMemoryError and build more resilient Java applications.
Was this solution helpful?