One of our applications was determined to be leaking memory. The leak was traced back to some stateful EJB’s that were extending Spring’s AbstractStatefulSession bean class. While I could not trace to the exact source of the leak, it seems to be related to the unloading of the BeanFactory.
As per the documentation, Spring’s default behavior will initialize a new ApplicationContext when the EJB object is created. It also states that the BeanFactory (which is the ApplicationContext) is unloaded when the EJB is removed.
One of the first things I checked was ensuring the EJB’s were in fact being removed. They were. At some point I remembered that in a more recent project, we changed the beanFactoryLocator to the ContextSingletonBeanFactoryLocator so that all EJBs use the same context (it also happens we setup the web application to use the same context too). The newer application did not have the memory leak so I decided to implement it here. I also figured that even if it didn’t fix the leak, this method is more efficient since there is no reason to have the context loaded everytime. To implement, I just overloaded the setSessionContext method:
Once implemented the leak went away. I never took the time to dig in and see what the true offender was, but it was found that some of the hibernate SingleTableEntityPersister objects were still present after leak. This could mean that it is Spring not properly cleaning things up or Hibernate itself has the leak.
As info this method was already implemented with our stateless EJB’s, so I could not confirm if the issue existed for AbstractStatelessSessionBean. However since both abstract classes use the unloadBeanFactory method from AbstractSessionBean, I would figure the issue would present itself — although due to Weblogic pooling the stateless EJB’s, it is probably not as noticable.
- Weblogic 8.1 sp4
- JRockit 1.4.2_13
- Spring 1.2.9
- Hibernate 3.2.5