Gradle "Out of memory" / "GC overhead limit exceeded" in CI
The Gradle daemon (or a build worker JVM) exhausted its heap. A large build, a memory-hungry task, or a tight default -Xmx on a small runner tips it into an OutOfMemoryError and the build dies.
What this error means
The build fails with java.lang.OutOfMemoryError: Java heap space or GC overhead limit exceeded, sometimes after the daemon was already running for a while. It correlates with build size and runner RAM rather than with your source code.
> Task :app:compileKotlin FAILED
Expiring Daemon because JVM heap space is exhausted
* What went wrong:
java.lang.OutOfMemoryError: Java heap spaceCommon causes
Daemon heap too small for the build
The default -Xmx for the Gradle daemon is lower than a large multi-module build, annotation processing, or Kotlin compilation needs, so the heap fills up.
Runner has too little RAM
A small CI runner cannot give the daemon and its workers enough memory; the OOM is an infrastructure-size problem, not a code bug.
How to fix it
Raise the Gradle daemon and worker heap
Set the JVM args in gradle.properties so the daemon and forked workers get more heap.
# gradle.properties
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
org.gradle.workers.max=2Run on a larger runner
- Move the job to a runner with more RAM so the daemon has headroom.
- Keep
-Xmxbelow the runner's total memory, leaving room for the OS and other workers. - For memory-heavy modules, lower
org.gradle.workers.maxto reduce concurrent heap pressure.
How to prevent it
- Set
org.gradle.jvmargsexplicitly rather than relying on the default heap. - Match the runner size to the build's real memory footprint.
- On Latchkey, self-healing managed runners auto-retry transient OOM-killed jobs and offer larger-RAM runner sizes so heap-bound builds get the memory they need.