Skip to content

Memory leak when running a lot of Junit & SpringBoot tests #36737

@pkernevez

Description

@pkernevez

I upgraded my project from SpringBoot 3.5.14 / Spring 6.2.18 to Spring Boot 4.0.6 / Spring 7.0.7

When I run my test suite, it fails due to OOM:

[ERROR] See /.../target/surefire-reports for the individual test results.
[ERROR] See dump files (if any exist) [date].dump, [date]-jvmRun[N].dump and [date].dumpstream.
[ERROR] There was an error in the forked process
[ERROR] java.lang.OutOfMemoryError: Java heap space
[ERROR] org.apache.maven.surefire.booter.SurefireBooterForkException: There was an error in the forked process
[ERROR] java.lang.OutOfMemoryError: Java heap space
[ERROR] 	at org.apache.maven.plugin.surefire.booterclient.ForkStarter.fork(ForkStarter.java:631)
[ERROR] 	at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:285)
[ERROR] 	at org.apache.maven.plugin.surefire.booterclient.ForkStarter.run(ForkStarter.java:250)
[ERROR] 	at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeProvider(AbstractSurefireMojo.java:1347)
[ERROR] 	at org.apache.maven.plugin.surefire.AbstractSurefireMojo.executeAfterPreconditionsChecked(AbstractSurefireMojo.java:1145)
[ERROR] 	at org.apache.maven.plugin.surefire.AbstractSurefireMojo.execute(AbstractSurefireMojo.java:979)
[ERROR] 	at org.apache.maven.plugin.DefaultBuildPluginManager.executeMojo(DefaultBuildPluginManager.java:126)

This OOM happens first in our CI (our runners have 4GB of total RAM). I can reproduce it locally by defining a parameter 'Xmx900m' for the forked JVM.

In production, the real Spring Boot application (version 3.5.x) is working perfectly with a Xmx500m.

The forked process is consuming more and more memory. This is the graph from gc logs of the test fork JVM.

I dump the memory file on the OOM. This is the first analysis I do:

Image

Main problem: 2, 3, 4, and 5

The issue 2, 3, 4 and 5, 123m for each AnnotationConfigApplicationContext.

In the JVM, I have 5 org.springframework.context.annotation.AnnotationConfigApplicationContext that retain 500m:

Image Image

2nd issue DefaultListableBeanFactory

The number 1 suspect is 11 instances of org.springframework.beans.factory.support.DefaultListableBeanFactory.

Image

This is an overview of our test:

Module Classes @Test methods SpringBoot JpaTest Mockito SpringExt Plain
Total 853 6 477 49 82 309 101 312

The full Mockito test doesn't rely on anything. The JPA & SpringBootTest test rely on test container (local stack & postgresql).

Do you have an idea for the origin of the 11 instances of DefaultListableBeanFactory?

And why do 4 AnnotationConfigApplicationContexts retain so much memory (and the last one very few), all of them loaded with the same class loader?

I can't share the heap dump, but I can do query on it if it's useful.

Are they not supposed to be singleton?

May be related to #34279.

Metadata

Metadata

Assignees

No one assigned

    Labels

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions