Uploaded image for project: 'Seam 2'
  1. Seam 2
  2. JBSEAM-4030

Spring integration leaks proxy classes causing permgen leak



      We are using Seam 2.1.1.GA with Spring integration. We have hit an issue where it looks like a new javassist proxy class is being created each time a Seam component is created.

      Normally the org.jboss.seam.Component caches the Class<ProxyObject> in its private 'factory' field. Each time a new instance of the component is required this cached class is used to create the instance.

      When using the Spring integration the Component is actually a org.jboss.seam.ioc.spring.SpringComponent which extends the org.jboss.seam.ioc.IoCComponent. The SpringComponent asks Spring for the instance and the IoCComponent wraps this in a javassist proxy wrapper.

      The issue that we are seeing is that the IoCComponent, in its instantiateJavaBean() method, uses ProxyUtils.enhance() to wrap the bean in javassist proxy, but does not, or is unable to, cache the Class<ProxyObject> created in the Component's 'factory' field. Therefore each time ProxyUtils.enhance() is called it creates a new class with a new name of the form XXX_$$_javassist_XXX using an incrementing counter. These generated classes are never cleaned up by the JVM and cause a slow memory leak.

      I can understand that as Seam is asking a 3rd party container (Spring) for the bean instance it cannot control the type of the bean that will be returned. It is possible for the bean to change type while the application is running and Seam would then need to create a new proxy class. However in the typical case the same proxy class can be reused to create a new instance for each new bean instance.

      My app has a number of event scoped Seam beans that are created/configured by Spring and the current implementation manges to run the VM out of permgen space in only a few minutes.

      A naive fix would be just to cache the proxy class and use it every time, but this would potentially impose additional restrictions on the 3rd party container. A more complete solution would be to use the type (class and interfaces) of the instance obtained from Spring to determine if a new proxy class needs to be built or if the cached proxy class can be reused.

      The naive fix approach can be seen in this forum post: http://www.seamframework.org/Community/Seam211GAWithSpringNewJavassistClassCreatedForEachNewComponentInstance
      In our application this resolved the issues we way with many proxy classes being built for each request, and therefore resolved our permgen issues.

        Gliffy Diagrams




              • Assignee:
                ncadell Nicko Cadell (Inactive)
              • Votes:
                1 Vote for this issue
                2 Start watching this issue


                • Created: