Skip to content
Latchkey

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.

gradle
> Task :app:compileKotlin FAILED
Expiring Daemon because JVM heap space is exhausted

* What went wrong:
java.lang.OutOfMemoryError: Java heap space

Diagnose it: JDK version and heap

Terminal
java -version 2>&1
echo "JAVA_HOME=$JAVA_HOME"
free -h

# class file 65 = Java 21, 61 = Java 17, 55 = Java 11
javap -verbose <SomeClass>.class | grep "major version"

Common 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
# gradle.properties
org.gradle.jvmargs=-Xmx4g -XX:MaxMetaspaceSize=1g
org.gradle.workers.max=2

Run on a larger runner

  1. Move the job to a runner with more RAM so the daemon has headroom.
  2. Keep -Xmx below the runner's total memory, leaving room for the OS and other workers.
  3. For memory-heavy modules, lower org.gradle.workers.max to reduce concurrent heap pressure.

How to prevent it

  • Set org.gradle.jvmargs explicitly 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.

Frequently asked questions

What causes Gradle "Out of memory" / "GC overhead limit exceeded" in CI?
There are 2 common causes: daemon heap too small for the build and runner has too little ram. 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.
How do I fix Gradle "Out of memory" / "GC overhead limit exceeded" in CI?
There are 2 fixes depending on which cause you have: raise the gradle daemon and worker heap and run on a larger runner. Work through them in order, since the first is the most common.
What does Gradle "Out of memory" / "GC overhead limit exceeded" in CI actually mean?
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.
How do I stop Gradle "Out of memory" / "GC overhead limit exceeded" in CI happening again?
Set org.gradle.jvmargs explicitly rather than relying on the default heap. The prevention section lists 3 changes that keep it from recurring.

Related guides

References

This is an out-of-memory kill, not an application error. Latchkey detects, repairs, and retries it for you. Start free → 30-day trial · No credit card