I am also experiencing this problem in a webapp. My understanding of Tomcat classloading if as follows, please correct if wrong.
Tomcat has a shared ClassLoader that can load up classes that all webapps can use. This ClassLoader will never be GCed as it lives for the lifetime of the Tomcat process. Tomcat creates a ClassLoader per webapp when it is deployed. If the webapp is undeployed Tomcat releases the ClassLoader. At this point the ClassLoader, it's Classes and all object instances of these classes should become GCable and be collected sometime in the future. Using Sun's 1.5.0_06 JDK if I set the max perm gen size to about 30MB the apps deploys fine the first time and then dies with OutOfMemory: PermSpace on a redeploy. I if set the perm gen to 64MB (the sun default) then it takes about 4/5 redeploys before the OOM. My hibernate SessionFactory is held in a static variable of a class so I can access it from wherever in want in my application. My understanding is that the static will get cleaned up when the webapp redeploys and releases the ClassLoader that created it, so I don't *think* this is the problem. I read somewhere that apache-commons logging stores cached references to Classes/ClassLoaders in a static map. Sure enough it does in the code of LogFactory and a call to LogFactory.releaseAll() will clean this cache out, but even with this call in the contextDestroyed of a ServletContextListener there was no obvious change in the behaviour, still got a perm space error as above. I did some debugging into the LogFactory to see what was happening, I saw the following behaviour. 1) Deploy Webapp 2) Call to LogFactory.cacheFactory() to store a ClassLoader(1)->LogFactory mapping in LogFactory.factoryCache 3) Undeploy Webapp 4) Call to LogFactory.releaseAll() from my ServletContextListener.contextDestroyed(). LogFactory.factoryCache is cleaned out. 5) Call to LogFactory.cacheFactory() AGAIN (see stack trace below) storing ClassLoader(1)->LogFactory again. 6) Redeploy Webapp. 7) Call to LogFactory.cacheFactory() (factoryCache is empty) storing ClassLoader(2)->LogFactory Note the numbering of the ClassLoaders to indicate different instances. The first ClassLoader gets put back in the LogFactory cache after I clean it out manually. Here's the stacktrace from the call to LogFactory.cacheFactory() java.lang.Exception: Stack trace at java.lang.Thread.dumpStack(Thread.java:1158) at org.apache.commons.logging.LogFactory.cacheFactory(LogFactory.java:497) at org.apache.commons.logging.LogFactory.getFactory(LogFactory.java:323) at org.apache.commons.logging.LogFactory.getLog(LogFactory.java:351) at org.hibernate.cache.ReadOnlyCache.<clinit>(ReadOnlyCache.java:16) at sun.misc.Unsafe.ensureClassInitialized(Native Method) at sun.reflect.UnsafeFieldAccessorFactory.newFieldAccessor(UnsafeFieldAcces sorFactory.java:25) at sun.reflect.ReflectionFactory.newFieldAccessor(ReflectionFactory.java:12 2) at java.lang.reflect.Field.acquireFieldAccessor(Field.java:917) at java.lang.reflect.Field.getFieldAccessor(Field.java:898) at java.lang.reflect.Field.get(Field.java:357) at org.apache.catalina.loader.WebappClassLoader.clearReferences(WebappClass Loader.java:1607) at org.apache.catalina.loader.WebappClassLoader.stop(WebappClassLoader.java :1491) at org.apache.catalina.loader.WebappLoader.stop(WebappLoader.java:706) at org.apache.catalina.core.StandardContext.stop(StandardContext.java:4535) at org.apache.catalina.core.ContainerBase.removeChild(ContainerBase.java:89 2) at org.apache.catalina.startup.HostConfig.checkResources(HostConfig.java:10 34) at org.apache.catalina.startup.HostConfig.check(HostConfig.java:1202) at org.apache.catalina.startup.HostConfig.lifecycleEvent(HostConfig.java:29 2) at org.apache.catalina.util.LifecycleSupport.fireLifecycleEvent(LifecycleSu pport.java:119) at org.apache.catalina.core.ContainerBase.backgroundProcess(ContainerBase.j ava:1305) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.proc essChildren(ContainerBase.java:1569) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.proc essChildren(ContainerBase.java:1578) at org.apache.catalina.core.ContainerBase$ContainerBackgroundProcessor.run( ContainerBase.java:1558) at java.lang.Thread.run(Thread.java:595) Looks like during the WebappClassLoader cleanup the logging is being reinitialised. I've reached my limit of knowledge on ClassLoaders and tomcat but I'm not sure why it would be doing a class initialisation when it's trying to cleanup the class loader. I'm not sure if this definitely my problem, maybe someone who's more familiar with ClassLoading issues can make something of this. Cheers. -----Original Message----- From: Caldarale, Charles R [mailto:[EMAIL PROTECTED] Sent: 28 November 2006 16:43 To: Tomcat Users List Subject: RE: Memory leaks on webapp redeploy > From: Christopher Schultz [mailto:[EMAIL PROTECTED] > Subject: Re: Memory leaks on webapp redeploy > > Maybe this issue has been fixed in recent VMs (IIRC, older VMs -- > maybe 1.3-era -- would never discard java.lang.Class objects. Not true either. I've been porting Sun's JVMs to various platforms since 1.2, and GC of classes has always been available (not sure about 1.1). > Java 1.5 has the "-Xnoclassgc" option That's also been around since at least 1.3. > For instance, if you had a singleton with a static instance of the > class, but no references to the Class object, no instances other than > the singleton (a reasonable assumption for a singleton), and no > outside references to the singleton object, then the VM is within it's > rights to discard both the instance and the Class since they are > "unused". I seem to recall this being a problem for folks who thought > that singletons were a good idea, and so the Java folks decided to keep > Class objects around forever. The first part is true, the latter conclusion isn't, at least not in Sun-based JVMs. You do have to be careful if only reflection is used to access a class, since it can disappear as you described. > Or am I just crazy and making the whole thing up? ;) Always a possibility, especially in this business :-) - Chuck THIS COMMUNICATION MAY CONTAIN CONFIDENTIAL AND/OR OTHERWISE PROPRIETARY MATERIAL and is thus for use only by the intended recipient. If you received this in error, please contact the sender and delete the e-mail and its attachments from all computers. --------------------------------------------------------------------- To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED] This e-mail is bound by the terms and conditions described at http://www.subexazure.com/mail-disclaimer.html --------------------------------------------------------------------- To start a new topic, e-mail: users@tomcat.apache.org To unsubscribe, e-mail: [EMAIL PROTECTED] For additional commands, e-mail: [EMAIL PROTECTED]