When deploying a webapp contain some TLDs and containing custom JAXP stuff, the web app is not completely removed when undeploying. The problem is that org.apache.catalina.startup.TldConfig has a static member tldDigester which uses a SAXParser. In my case a parser from the web app is being used. So since the parser (its class is loaded with the WebAppClassLoader) will be referenced from the TldConfig class (which is loaded with the StandardClassLoader) the web app class loader never gets collected which leads to a full permspace after a few redeploys. How to reproduce: Create a WAR containing an empty web.xml and jstl-1.1.2.jar, standard- 1.1.2.jar (both from Jakarta Taglibs project), xercesImpl-2.9.0.jar and xml- apis-2.9.0.jar (both from Xerces project). Run a tomcat containing just the manager web app. Deploy the WAR. Undeploy the WAR. Take a heap dump (e.g. using jmap). Analyse the dump (e.g. using jhat). Browse to the class of org.apache.catalina.startup.TldConfig. See that it is being loaded by the StandardClassLoader. Browse to the object pointed to by the tldDigester static member. Jump to the object pointed to by the parser instance member. In this example it is an org.apache.xerces.jaxp.SAXParserImpl. Jump the class of this object. See that it is being loaded by the WebAppClassLoader. This is why the WebAppClassloader will never be collected. I am using JDK 1.6.0_02.
Sorry, but I can not attach the WAR described above since I can not compress it to be smaller than 1000kb.
An easy fix would be to make the tldDigester member in TldConfig not static. This would cost some extra cycles when deploying applications, but that would be OK for me if it fixes a memory leak.
*** This bug has been marked as a duplicate of bug 29936 ***