Skip to content
Latchkey

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.

JVM output
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.

Terminal
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.

Terminal
java -XX:+HeapDumpOnOutOfMemoryError -XX:HeapDumpPath=./oom.hprof -jar app.jar
# analyze oom.hprof with Eclipse MAT or VisualVM

How to prevent it

  • Size -Xmx so 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.

Frequently asked questions

What causes ""GC overhead limit exceeded""?
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.
How do I fix "GC overhead limit exceeded"?
A larger -Xmx gives GC room to reclaim, ending the thrashing - assuming there is no leak.
Can Latchkey fix this automatically?
Yes. Latchkey runs your GitHub Actions on managed runners that detect this failure, apply the fix, and retry the job automatically - self-healing is on by default.

Related guides

References

Latchkey auto-heals failures like this one - detected, fixed, and retried without you. Start free → 30-day trial · No credit card