]
Jean-Frederic Clere closed JBWEB-242.
-------------------------------------
Resolution: Done
Memory Leak in PerThreadTagHandlerPool
--------------------------------------
Key: JBWEB-242
URL:
https://issues.jboss.org/browse/JBWEB-242
Project: JBoss Web
Issue Type: Bug
Security Level: Public(Everyone can see)
Components: Tomcat
Affects Versions: JBossWeb-7.0.16.GA
Reporter: Martin Ball
Assignee: Remy Maucherat
Attachments: JBWEB-242.patch, tagLeakTest.jmx, tagLeakTest.tar
org.apache.jasper.runtime.PerThreadTagHandlerPool is leaking memory because reuse() does
not call instanceManager.destroyInstance(handler) when the pool is full. This happens if
the number of nested tags of the same instance > Constants.MAX_POOL_SIZE ( or
OPTION_MAXSIZE if set)
The instance manager in as 7.1.x implemented by
org.jboss.as.web.deployment.WebInjectionContainer contains a map which holds references to
the tag instances and as these are never removed the map grows over time until the heap is
exhausted.
It is worth listing three possible workarounds before I go on to the fix:
1. Disable the instance manager by setting the system property
org.apache.jasper.Constants.USE_INSTANCE_MANAGER_FOR_TAGS=false
2. Disable tag pooling in the jboss configuration (not tried this personally) - see post
by jaikiran pai:
https://community.jboss.org/thread/174669
3. Set the pool size to be greater than the maximum level of nesting by setting the
system property org.apache.jasper.Constants.MAX_POOL_SIZE. Not ideal as there is no
guarantee that this won't be exceeded and memory will still leak.
Looking at the commit history of PerThreadTagHandlerPool I can see that in revision 1697
the code that deals with getting and releasing tags via the instance manager was copied
from TagHandlerPool, but the code in the reuse() method of TagHandlerPool was not copied
and in fact the instance manager code was removed from TagHandlerPool. So it looks like
both classes have this issue. I am assuming that we should always call
instanceManager.destroyInstance(handler) when releasing a tag?
I have a simple test war that reproduces the problem and I have reintroduced the call to
instanceManager.destroyInstance(handler) in PerThreadTagHandlerPool and it fixes the leak.
I will attach both war and patch to the issue.
I am curious as to why the try/catch around instanceManager.destroyInstance(handler) in
release() is ignoring the exceptions that can be thrown? I would have thought that either
the specific exceptions should be caught, which would allow runtime exceptions to
propagate (perhaps undesirable) or it should log whatever exception is caught as a warn or
debug message? Anyway not my call, so I have just copied the code verbatim from release().
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: