Java "OutOfMemoryError: Java heap space" in CI
The JVM tried to allocate an object but the heap was full and the garbage collector could not reclaim enough. The process throws OutOfMemoryError and, in CI, the step usually dies right there.
What this error means
A test or application run aborts with java.lang.OutOfMemoryError: Java heap space, often mid-task after memory has been climbing. It tracks with data size and -Xmx rather than being a deterministic code error.
Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
at java.base/java.util.Arrays.copyOf(Arrays.java:3537)
at com.example.Report.load(Report.java:88)Common causes
Heap limit too low for the workload
The default or configured -Xmx is smaller than what the run actually needs to hold in memory at peak, so a legitimately large workload overflows.
Memory leak or unbounded allocation
Holding references in a static collection, loading an entire file into memory, or an unbounded cache grows the live set until the heap is exhausted.
How to fix it
Raise the heap for the JVM that fails
Set -Xmx on the exact process (test JVM, app, or build worker) that runs out, sized below the runner's RAM.
# for a plain run
java -Xmx4g -jar app.jar
# for Maven Surefire test JVMs
export MAVEN_OPTS="-Xmx2g"
mvn testFind and fix the leak
- Add
-XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./oom.hprofand analyze the dump. - Look for static collections that only grow, or full-file reads that should be streamed.
- Bound caches and release references once the data is no longer needed.
How to prevent it
- Set an explicit
-Xmxthat reflects the real peak working set. - Stream large inputs instead of loading them fully into memory.
- On Latchkey, self-healing managed runners auto-retry transient OOM-killed jobs and offer larger-RAM runner sizes for memory-heavy workloads.