Spring integration leaks proxy classes causing permgen leak
-----------------------------------------------------------
Key: JBSEAM-4030
URL:
https://jira.jboss.org/jira/browse/JBSEAM-4030
Project: Seam
Issue Type: Bug
Components: Spring
Affects Versions: 2.1.1.GA
Environment: JVM 1.6.0_10
Reporter: Nicko Cadell
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/Seam211GAWithSpringNewJavassistCla...
In our application this resolved the issues we way with many proxy classes being built for
each request, and therefore resolved our permgen issues.
--
This message is automatically generated by JIRA.
-
If you think it was sent incorrectly contact one of the administrators:
https://jira.jboss.org/jira/secure/Administrators.jspa
-
For more information on JIRA, see:
http://www.atlassian.com/software/jira