Java "OutOfMemoryError: Metaspace" in CI - Fix Class Metadata Limits
The JVM ran out of Metaspace - the native memory region that stores class metadata. Unlike heap, this fills with loaded classes, so heavy class loading or a classloader leak exhausts it.
What this error means
A build or test run fails with java.lang.OutOfMemoryError: Metaspace. Raising -Xmx does not help, because Metaspace is separate from the Java heap.
java.lang.OutOfMemoryError: Metaspace
at java.base/java.lang.ClassLoader.defineClass1(Native Method)
at java.base/java.lang.ClassLoader.defineClass(ClassLoader.java:1027)Common causes
MaxMetaspaceSize too low for the class count
Large frameworks, many annotation processors, and big test suites load tens of thousands of classes. A capped -XX:MaxMetaspaceSize smaller than that fills up.
Classloader leak in a long-lived JVM
A reused daemon or app server that repeatedly loads classes without unloading old classloaders leaks Metaspace until it is exhausted.
How to fix it
Raise or unbound MaxMetaspaceSize
Increase the Metaspace cap (it is separate from heap).
java -XX:MaxMetaspaceSize=512m -jar app.jar
# Gradle daemon (gradle.properties):
# org.gradle.jvmargs=-Xmx2g -XX:MaxMetaspaceSize=1gReduce class-loading pressure
- Use a fresh JVM per build in CI (
--no-daemon) so Metaspace does not accumulate. - Lower test fork parallelism so fewer JVMs load the full class set at once.
- Investigate classloader leaks if a long-lived JVM is involved.
How to prevent it
- Set
MaxMetaspaceSizegenerously when many classes load, or leave it unbounded with enough native RAM. - Prefer fresh JVMs (
--no-daemon) in ephemeral CI. - Watch for classloader leaks in reused processes.
Frequently asked questions
Why does raising -Xmx not fix a Metaspace OOM?
-Xmx controls the Java heap, which stores objects. Metaspace is a separate native region for class metadata, controlled by -XX:MaxMetaspaceSize. A Metaspace OOM needs that flag, not heap.