Christophe Bismuth opened SPR-15380 and commented

Hi,

I have a memory leak issue, I may have misused Spring Java configuration capabilities.

  • I start a Tomcat application server 8.5 instance with default management application and my Spring 4 application (the only Spring application in Tomcat)
  • I stop only my application from the Tomcat manager UI
  • I click on the "Find leaks" button from the Tomcat Manager UI to trigger a full Java GC
  • Tomcat says my application causes memory leaks
  • I open JProfiler and take a full Java Heap snapshot

As shown in attachments:

  • Some Spring classes aren't collected
  • My Spring components are all collected
  • My Spring configuration CGLIB proxies are not collected
  • It seems to exist to cyclic dependency between these proxies

Should everything related to Spring be collected after application being stopped?


Affects: 4.2.9, 4.3.7

Attachments: - Heap_Walker_Classes_Application.csv (1.26 kB) - Heap_Walker_Classes_Spring.csv (7.93 kB) - javaconfig.png (198.87 kB) - screencapture-file-home-cbismuth-Desktop-Heap_Walker_Classes_2-html-1490518670213.png (177.86 kB) - screencapture-file-home-cbismuth-Desktop-Heap_Walker_Classes-html-1490518604963.png (859.39 kB) - screencapture-file-home-cbismuth-Desktop-Heap_walker_Incoming_References-html-1490518709454.png (162.86 kB)

Comment From: spring-projects-issues

Christophe Bismuth commented

This is not an issue: Tomcat doesn't expire session when stopping the application.

Comment From: spring-projects-issues

Juergen Hoeller commented

In general, we are trying for everything to be collectible, at least as far as application state goes. Session management in the Servlet container may indeed prevent proper garbage collection here, as may the Servlet container's ClassLoader management...

Comment From: spring-projects-issues

Christophe Bismuth commented

I retried from scratch by expiring sessions first, but still having this issue. My previous comment was wrong, sorry.

Comment From: spring-projects-issues

Stéphane Nicoll commented

Christophe can you please attach a sample? As you've figured out yourself, this looks like a tricky use case and I prefer to spend quality time debugging the actual problem than trying to reproduce it.

Comment From: spring-projects-issues

Christophe Bismuth commented

Yes Stéphane, I'll craft a minimal project and push it to GitHub, thank you.

Comment From: spring-projects-issues

Christophe Bismuth commented

Dear Juergen and Stéphane, I took time to upgrade our Application to Spring Boot integration for Vaadin with WAR Maven packaging. Since then, every single Spring, Vaadin and application related classes are now fully collected when stopping the application from the Tomcat manager UI.

Sorry for this finally-no-bug issue, I have no doubt I messed things up while trying to manage Servlet and Spring context lifecyles.

Thank you, Christophe

http://vaadin.github.io/spring-tutorial/

For future readers, here is below our Vaadin Spring configuration when using WAR packaging.

@Configuration
@EnableVaadin
@Import(ApplicationConfig.class)
public class GdCWebApplication extends SpringBootServletInitializer {

    @Bean
    @Scope(SCOPE_PROTOTYPE)
    public UI ui() {
        return new GdCWebUI();
    }

    @Bean
    public ServletRegistrationBean servletRegistrationBean() {
        return new ServletRegistrationBean(new SpringVaadinServlet(), "/*", "/VAADIN/*");
    }
}

Comment From: spring-projects-issues

Juergen Hoeller commented

No worries, marking this issue as 'invalid' then...

Comment From: spring-projects-issues

Christophe Bismuth commented

Here I am again, I reproduced the issue, here is below a tiny project to reproduce it easily.

https://github.com/cbismuth/SPR-15380

I can try to dig deeper, feel free to ask, I'd glad to help.

Comment From: spring-projects-issues

Stéphane Nicoll commented

Christophe Bismuth thanks for the sample! I can't reproduce with the instructions on that repository

No web applications appear to have triggered a memory leak on stop, reload or undeploy.

Also, Vaadin is the one using the Session so I am not sure where the problem would be...

Comment From: spring-projects-issues

Christophe Bismuth commented

Thank you Stéphane for your valuable time, that's really good news.

Could you please tell me what OS, Tomcat and JDK you are using please?

Comment From: spring-projects-issues

Stéphane Nicoll commented

Tomcat 8.5.12, MacOS, JDK 1.8.0_121

If you could reproduce the problem without Vaadin, that would be a very good step to continue the conversation here. Or help me reproduce the problem on my end.

Comment From: spring-projects-issues

Christophe Bismuth commented

Yes Stéphane, I'll try to do so, thank you.

Comment From: spring-projects-issues

Christophe Bismuth commented

You're right Stéphane, with the supplied test case:

  • When not opening a Vaadin session, I can stop and undeploy application without any memory leak and Spring application is successfully started and stopped (I've checked the logs).
  • When opening a single Vaadin session and expire it, I can stop and undeploy application without any memory leak and Spring application is successfully started and stopped (I've checked the logs).
  • When opening a Vaadin session and +not+ expire it, Tomcat warns about memory leaks after stopping the application.

I'll try to isolate this behavior a little bit more.

This bug seems to be more related to Vaadin session management. https://github.com/vaadin/framework/issues/8959

Thank you for your time.

Comment From: spring-projects-issues

Christophe Bismuth commented

Quick follow up: updated to Vaadin Spring 2.0.1 and no change (same leaks).

Comment From: snicoll

Closing as we established quite some time ago to not be related to the core container.