Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Upgrade from 3.3.5 to 3.4.1: SpringBootTests throw OutOfMemoryError #34279

Open
Christian-Harnisch-DB opened this issue Jan 17, 2025 · 5 comments
Labels
in: test Issues in the test module status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged or decided on

Comments

@Christian-Harnisch-DB
Copy link

  • In our test setup code, we have a ContextConfiguration which adds beans to the application context (MockWebServer and GreenMail instances, which are shut down on ContextClosedEvent by calling their stop() and shutdown() methods)
  • The SpringBootTests additionally use the following annotations: @DirtiesContext(classMode = AFTER_EACH_TEST_METHOD) and @TestInstance(PER_METHOD)
  • With Spring Boot 3.3.5 the tests execute successfully
  • With 3.4.1 the tests fail with an out of memory exception (java.lang.OutOfMemoryError: Java heap space)
  • When profiling the test runs, we observe that over 400 instances of org.springframework.boot.web.servlet.context.AnnotationConfigServletWebServerApplicationContext are referenced from org.springframework.beans.factory.support.DefaultListableBeanFactory. It appears that this is about one instance per SpringBootTest.
  • With 3.3.5, the profiler (YourKit) marks them as [Weak/Soft Reachable], whereas in 3.4.1 it doesn't (are they strong references now?)
  • We are not sure if there is a new leak, or if existed before and only now exhausts heap space

Example stacktrace:

Caused by: org.springframework.beans.factory.BeanCreationException: Error creating bean with name 'xyz' defined in class path resource [abc.class]: Unexpected exception during bean creation
	at app//org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.createBean(AbstractAutowireCapableBeanFactory.java:536)
	at app//org.springframework.beans.factory.support.AbstractBeanFactory.lambda$doGetBean$0(AbstractBeanFactory.java:336)
	at app//org.springframework.beans.factory.support.DefaultSingletonBeanRegistry.getSingleton(DefaultSingletonBeanRegistry.java:289)
	at app//org.springframework.beans.factory.support.AbstractBeanFactory.doGetBean(AbstractBeanFactory.java:334)
	at app//org.springframework.beans.factory.support.AbstractBeanFactory.getBean(AbstractBeanFactory.java:199)
	at app//org.springframework.beans.factory.config.DependencyDescriptor.resolveCandidate(DependencyDescriptor.java:254)
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.addCandidateEntry(DefaultListableBeanFactory.java:1883)
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.findAutowireCandidates(DefaultListableBeanFactory.java:1847)
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeanCollection(DefaultListableBeanFactory.java:1737)
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveMultipleBeans(DefaultListableBeanFactory.java:1705)
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.doResolveDependency(DefaultListableBeanFactory.java:1580)
	at app//org.springframework.beans.factory.support.DefaultListableBeanFactory.resolveDependency(DefaultListableBeanFactory.java:1519)
	at app//org.springframework.beans.factory.support.ConstructorResolver.resolveAutowiredArgument(ConstructorResolver.java:913)
	at app//org.springframework.beans.factory.support.ConstructorResolver.createArgumentArray(ConstructorResolver.java:791)
	... 100 more
Caused by: java.lang.OutOfMemoryError: Java heap space

Environment:

  • JDK Version: OpenJDK Runtime Environment Temurin-21.0.5+11 (build 21.0.5+11-LTS)
  • Operating System: Windows 11
  • Spring Boot Version: 3.4.1 (issue occurs), 3.3.5 (no issue)
  • Build system: Gradle Wrapper 8.12

Attempted solutions:

  • Set server.shutdown to immediate
  • Tried jetty and undertow instead of tomcat
@spring-projects-issues spring-projects-issues added the status: waiting-for-triage An issue we've not yet triaged or decided on label Jan 17, 2025
@snicoll
Copy link
Member

snicoll commented Jan 17, 2025

When profiling the test runs, we observe that over 400 instances of

That looks odd to me as the cache has a default size of 32. Did you increase the size (using spring.test.context.cache.maxSize or by creating your own?)

@snicoll snicoll added the status: waiting-for-feedback We need additional information before we can continue label Jan 17, 2025
@snicoll snicoll transferred this issue from spring-projects/spring-boot Jan 17, 2025
@snicoll snicoll added the in: test Issues in the test module label Jan 17, 2025
@Christian-Harnisch-DB
Copy link
Author

That looks odd to me as the cache has a default size of 32. Did you increase the size (using spring.test.context.cache.maxSize or by creating your own?)

No, we neither increased the cache size nor created our own.

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue labels Jan 17, 2025
@sbrannen
Copy link
Member

Thanks for the feedback, @Christian-Harnisch-DB.

Though without a means to observe the behavior you're describing, it will be very difficult for us to determine the cause.

In light of that, please provide us a minimal sample application (or all-in-one test class) that reproduces the issue, preferably something that we can download and run ourselves (such as public Git repository or a ZIP file attached to this issue).

Thanks in advance!

@sbrannen sbrannen added status: waiting-for-feedback We need additional information before we can continue and removed status: feedback-provided Feedback has been provided labels Jan 17, 2025
@spring-projects-issues
Copy link
Collaborator

If you would like us to look at this issue, please provide the requested information. If the information is not provided within the next 7 days this issue will be closed.

@spring-projects-issues spring-projects-issues added the status: feedback-reminder We've sent a reminder that we need additional information before we can continue label Jan 24, 2025
@Christian-Harnisch-DB
Copy link
Author

Sorry for the delay, I'm sort of confused by this memory leak.

I uploaded a demo project in the attached ZIP file. This is freshly generated using Spring Initializr, I only added that DemoApplicationTests.contextLoads() runs numerous times instead of once. If you let it run for some minutes, you should see the heap usage grow over time like in the attached screenshot.

In our actual code, we don't need that many test runs. I think this is because the demo contains no additional code, so it's just standard Spring beans occupying memory. I'm not sure, though.

memleakdemo.zip

Image

@spring-projects-issues spring-projects-issues added status: feedback-provided Feedback has been provided and removed status: waiting-for-feedback We need additional information before we can continue status: feedback-reminder We've sent a reminder that we need additional information before we can continue labels Jan 28, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
in: test Issues in the test module status: feedback-provided Feedback has been provided status: waiting-for-triage An issue we've not yet triaged or decided on
Projects
None yet
Development

No branches or pull requests

4 participants