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.

        Attachments

          Activity

            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:
                3 years, 46 weeks, 6 days ago