Java "GC overhead limit exceeded" in CI - Fix Thrashing GC
The JVM gave up because it was spending more than 98% of its time in garbage collection and recovering less than 2% of the heap. It is a near-OOM: technically there is a sliver of heap left, but GC is thrashing.
What this error means
A long-running test or build slows to a crawl and then fails with java.lang.OutOfMemoryError: GC overhead limit exceeded. CPU is pegged on GC threads just before the failure.
Exception in thread "main" java.lang.OutOfMemoryError: GC overhead limit exceeded
at java.base/java.util.HashMap.resize(HashMap.java:704)Common causes
Heap too small for the live set
When the live data nearly fills the heap, GC runs constantly but frees almost nothing. The overhead guard trips before a hard heap-space OOM.
Memory leak slowly filling the heap
A growing retained set (caches, accumulating collections) pushes the heap toward full, and GC overhead climbs until the limit is exceeded.
How to fix it
Increase the heap
A larger -Xmx gives GC room to reclaim, ending the thrashing - assuming there is no leak.
java -Xmx4g -jar app.jar
mvn -B test -DargLine="-Xmx2g"Find and fix the retention
If raising heap only delays the failure, capture a heap dump and locate what is being retained.
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./oom.hprof -jar app.jar
# analyze oom.hprof with Eclipse MAT or VisualVMHow to prevent it
- Size
-Xmxso the live set leaves comfortable headroom for GC. - Profile for leaks when GC overhead climbs over time.
- Avoid unbounded in-memory accumulation in long-running steps.