Skip to content

Java config FactoryBean proxy causes class loader leak [SPR-9274] #13912

@spring-projects-issues

Description

@spring-projects-issues
Collaborator

Harald Wellmann opened SPR-9274 and commented

Redeploying my web application in Tomcat a couple of times in a row, I had a PermGen space OutOfMemoryError. A heap dump revealed the cause to be a net.sf.cglib.proxy.Callback stored in thread-local memory, so that the associated class loader could not get garbage collected.

The callback holds a reference to ConfigurationClassEnhancer.GetObjectMethodInterceptor, which brought me closer to the root cause of the problem.

After changing my Spring Configuration from

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(myEntityManagerFactory().getObject());
    }

    @Bean
    public AbstractEntityManagerFactoryBean myEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
        bean.setDataSource(myDataSource);
        bean.setPersistenceProvider(new HibernatePersistence());
        bean.setPersistenceUnitName("myPU");
        return bean;
    }

to

    @Bean
    public PlatformTransactionManager transactionManager() {
        return new JpaTransactionManager(myEntityManagerFactory());
    }

    @Bean
    public EntityManagerFactory tcmEntityManagerFactory() {
        LocalContainerEntityManagerFactoryBean bean = new LocalContainerEntityManagerFactoryBean();
        bean.setDataSource(myDataSource);
        bean.setPersistenceProvider(new HibernatePersistence());
        bean.setPersistenceUnitName("myPU");
        bean.afterPropertiesSet();
        return bean.getObject();
    }

I can redeploy my application without memory leaks.

I suspect the problem would disappear if ConfigurationClassEnhancer.enhanceFactoryBean() called Enhancer.registerStaticCallbacks() instead of Enhancer.registerCallbacks() (see #10601).


Affects: 3.1 GA, 3.2.8

Issue Links:

Backported to: 3.2.9

5 votes, 5 watchers

Activity

spring-projects-issues

spring-projects-issues commented on Jun 5, 2012

@spring-projects-issues
CollaboratorAuthor

Peter Ertl commented

I can confirm this memory issue and it's pretty serious imho. It actually wasted so much memory on our integration system (> 1GB) that in the end the tests died with OOME, taking forever since GC was using up most of time (> 1h30m instead of 16min). I would upgrade the severity to at least 'serious' since having this bug means that people upgrading to javaconfig will have tests that do not run in a real-life application.

I created a local copy of class org.springframework.context.annotation.ConfigurationClassEnhancer and replaced
Enhancer.registerCallbacks() with Enhancer.registerStaticCallbacks() as Harald suggested. That fixed the issue here.

spring-projects-issues

spring-projects-issues commented on Jun 5, 2012

@spring-projects-issues
CollaboratorAuthor

Peter Ertl commented

I would also suggest to add a call to Enhancer.registerCallback(obj.getClass(), null) in DisposableBeanMethodInterceptor to clean up thread local callbacks like that:

  private static class DisposableBeanMethodInterceptor implements MethodInterceptor {

    @Override
    public Object intercept(final Object obj, final Method method, final Object[] args, final MethodProxy proxy) throws Throwable {
      Enhancer.registerStaticCallbacks(obj.getClass(), null);
      >>>>  Enhancer.registerCallbacks(obj.getClass(), null);

spring-projects-issues

spring-projects-issues commented on Apr 28, 2014

@spring-projects-issues
CollaboratorAuthor

Juergen Hoeller commented

The underlying problem has been addressed in the 4.0 line through a wider-scale revision of configuration class processing (#14941).

That said, since that registerCallbacks call in enhanceFactoryBean is still there in the 3.2.x line, I'll locally fix it there as well - for the 3.2.9 release.

Sorry that it took so long... This issue unfortunately wasn't ever noticed.

Juergen

added
status: backportedAn issue that has been backported to maintenance branches
in: coreIssues in core modules (aop, beans, core, context, expression)
on Jan 11, 2019
added this to the 4.0 GA milestone on Jan 11, 2019
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

in: coreIssues in core modules (aop, beans, core, context, expression)status: backportedAn issue that has been backported to maintenance branchestype: bugA general bug

Type

No type

Projects

No projects

Relationships

None yet

    Development

    No branches or pull requests

      Participants

      @jhoeller@spring-projects-issues

      Issue actions

        Java config FactoryBean proxy causes class loader leak [SPR-9274] · Issue #13912 · spring-projects/spring-framework