Uploaded image for project: 'Spring Framework'
  1. Spring Framework
  2. SPR-7385

org.aspectj.weaver.World.reset() not called on Context-Shutdown: Memory-Leak caused

    Details

    • Type: Bug
    • Status: Resolved
    • Priority: Major
    • Resolution: Won't Fix
    • Affects Version/s: 2.5.6
    • Fix Version/s: None
    • Component/s: Core:AOP
    • Labels:
      None
    • Last commented by a User:
      false

      Description

      When using Spring together with AspektJ a memory leak occurs. This memory leak prevents the application context and associated instances from beeing cleaned up. Root of this memory leak is the class org.aspectj.weaver.ResolvedType which contains public static final fields which will be populated with an (runtime) instance of class org.aspectj.weaver.World / org.aspectj.weaver.reflect.ReflectionWorld. Following the reference tree the ReflectionWorld instance has a reference to an org.springframework.aop.aspectj.AspectJExpressionPointcut$BeanNamePointcutDeignatorHandler instance which inturn has a reference path to the ApplicationContext. This reference to the ApplicationContext ( a XmlWebApplicationContext in our case ) "protects" the context and some application beans (especially ApplicationListeners) from beeing cleaned up by the GC. Thus continious re-deploment the web application causes an OutOfMemoryError after a while.

      There are two solutions that come into my mind:

      1. Calling org.aspectj.weaver.World.reset() on application context shutdown/close. This method clears all World/ReflectionWorld instances in ResolvedType static final memebers thus making them eligible for garbage collection. This will be the option i'll try. I plan to create a Bean as an ApplicationListener which creates and starts a new thread if it receives a ContextClosedEvent. This new thread waits until context.isActive() == false and calls World.reset() than. Afterwards the Thread will end so that it can be cleaned up itself. The risk/bad thing with that option is, if another ApplicationContext exists in the same VM/Classloader using AspectJ this process could clear their static world as well. I really don't know if that is the case / if that really happens. In our case using Tomcat the webapp will be loaded in it's own Classloader so the application context only clears the aspectj world of it's own classloader and does not affect other applications deployen at the same tomcat.

      2. From a spring perspektive the best thing could be removing the org.springframework.aop.aspectj.AspectJExpressionPointcut$BeanNamePointcutDeignatorHandler from the pointcutDesignators set of org.aspectj.weaver.reflect.ReflectionWorld thus enabling the cleanup of the application context with the overhead of the remaining AspectJ instances.

        Activity

        Hide
        jonseymour Jon Seymour added a comment -

        Here's a link to a bug report that I have filed with AspectJ that describes a scenario that can result in this issue unexpectedly pinning a large amount of memory.

        https://bugs.eclipse.org/bugs/show_bug.cgi?id=328558

        Show
        jonseymour Jon Seymour added a comment - Here's a link to a bug report that I have filed with AspectJ that describes a scenario that can result in this issue unexpectedly pinning a large amount of memory. https://bugs.eclipse.org/bugs/show_bug.cgi?id=328558
        Hide
        melix Cédric Champeau added a comment -

        Any update on this ? I am facing a similar problem in an application which periodically creates application contexts. Those contexts inherit a parent one, so the solution of cleaning up the world doesn't work.

        Seen on Spring 3.0.3.

        Show
        melix Cédric Champeau added a comment - Any update on this ? I am facing a similar problem in an application which periodically creates application contexts. Those contexts inherit a parent one, so the solution of cleaning up the world doesn't work. Seen on Spring 3.0.3.
        Hide
        cbeams Chris Beams added a comment -

        Andy, please triage as time allows. De-scheduling from 3.1 RC1 until that is complete.

        Show
        cbeams Chris Beams added a comment - Andy, please triage as time allows. De-scheduling from 3.1 RC1 until that is complete.
        Hide
        stefan penndorf Stefan Penndorf added a comment -

        Please note that this bug does not occur in AspectJ 1.7.4 anymore because AspectJ guys removed the static fields and moved to instance fields. The static World.reset() method is a No-Op in 1.7.4

        Show
        stefan penndorf Stefan Penndorf added a comment - Please note that this bug does not occur in AspectJ 1.7.4 anymore because AspectJ guys removed the static fields and moved to instance fields. The static World.reset() method is a No-Op in 1.7.4
        Hide
        juergen.hoeller Juergen Hoeller added a comment -

        Alright, I'll mark this as Won't Fix then. AspectJ 1.7.4 is around since Spring Framework 3.2.5 and recommended since that time anyway... And as of Spring Framework 4.0.4, we even recommend the use of Aspect J 1.8(.1).

        Juergen

        Show
        juergen.hoeller Juergen Hoeller added a comment - Alright, I'll mark this as Won't Fix then. AspectJ 1.7.4 is around since Spring Framework 3.2.5 and recommended since that time anyway... And as of Spring Framework 4.0.4, we even recommend the use of Aspect J 1.8(.1). Juergen

          People

          • Assignee:
            aclement Andy Clement
            Reporter:
            stefan penndorf Stefan Penndorf
            Last updater:
            Juergen Hoeller
          • Votes:
            5 Vote for this issue
            Watchers:
            6 Start watching this issue

            Dates

            • Created:
              Updated:
              Resolved:
              Days since last comment:
              47 weeks, 5 days ago