Tomcat 5.0.16 leaks a lot of memory when a webapp is reloaded. To duplicate, start Tomcat. Open Windows Task manager and view memory information for the java.exe process. Go to Tomcat Manager. Reload Tomcat Admin webapp. Memory will increase for each reload request. Memory also leaks when stopping/starting a webapp, but not as much as reload. I lost about 15 megabytes of memory after about 10 reload requests. I waited about 10 to 15 minutes to see if memory ever went back down, but it never did.
Please post on tomcat-user about this. This is a recurrent non issue. If you want to reopen this bug, please use a profiler and point out leaked references (under Tomcat's control, obviously).
I believe this is a bug within Tomcat... Here is a way to replicate it: Use the Struts blank war. Available here: http://mirrors.isc.org/pub/apache/jakarta/struts/binaries/jakarta-struts-1.1.zip Load that webapp, and open two browser windows, one to the Tomcat Manager and one to the Tomcat Status page. View the available memory. You will see it cycle within a meg as garbage collection is run. Then use Tomcat Manager to reload the struts webapp. The free memory should now be a meg less. This will continue until you reach 0, when a major garbage collection will occur, but it just looks like memory is released, as the Total Memory usage has now increased. You can continue this cycle until the memory reaches the total allocated, and Tomcat will fall over. If this is truly a "non issue", then I feel the Tomcat developers need to answer this issue more directly (like the release notes). We have customers that run multiple occurrences of our webapp under a single Tomcat, and need to reload... With the leak... they end up having to restart Tomcat to free the memory... causing support issues. I look forward to become more educated on why this is (not) an issue...
I looked into that already. While the classloader is not being garbage collected (this is the only object not being GCed) due to an unknown reason, no references are kept to it (as seen in a profiler), so from the Tomcat programming perspective, there's nothing to fix. Many "simple" webapps reload without leaking memory, but Struts webapps seem to pose a problem. Of course, there are also ways for a shared library to cause GC trouble when reloading, and this cannot be fixed, so you cannot assume a webapp reload will never leak memory. There's nothing in the release notes, because there's no conclusive information available.
*** Bug 32709 has been marked as a duplicate of this bug. ***
I would have to agree, a memory leak of this magnitude renders the Manager application useless. If this is something that the Tomcat team will not address, it should be noted in the release notes, or in the Manager App HOW-TO. Our organization made number of decisions based on the functionality of the Manager app that were thrown out once we observed this memory leak. Although there may be no conclusive evidence showing this is a problem in Tomcat, a number of people have consistently observed this behavior in the Manager application, and would agree that it is not desired behavior. To save other organizations from going through the problems we did, a simple blurb about this known behavior would be more that appreciated. Thanks, James Norman
After seaching the net I found that there indeed exists a problem with Struts that prevents web app class loaders from beeing garbage collected. The problem is that java beans information used by Struts is cached by java.beans.Introspector and never removed. A call to one of the methods java.beans.Introspector.flushCaches(), java.beans.Introspector.flushCaches (Class) or org.apache.commons.beanutils.PropertyUtilsBean.clearDescriptors() would solve this. After doing a bit more searching I found that the Spring framework solves this problem by providing a servlet context listener class (http://www.springframework.org/docs/api/org/springframework/web/util/Introspec torCleanupListener.html) that calls Introspector.flushCaches() when a context is destroyed. To test this, I modified the web.xml of the struts-examples web app to include a listener definition using IntrospectorCleanupListener. After that I ran the WebPageConnector test program posted by James Norman on bug 32709. The program ran over 1500 redeploys before i turned it off, at which time the memory consumed by Tomcat (5.5) was about 30MB. Before the modification the program could only run about 110 redeploys before an OutOfMemoryError occurred.
Very good finding ! I think I will add that to the stop method of the classloader, like there is a method to clear the classloader in commons-logging. This is a very sneaky issue as the references to the classloader are never displayed by profilers ... Any other cool features like this in the JDK ? The comment in the JDK source is hilarious: /** * Flush all of the Introspector's internal caches. This method is * not normally required. It is normally only needed by advanced * tools that update existing "Class" objects in-place and need * to make the Introspector re-analyze existing Class objects. */
That got it. Thanks to all who resolved this, we can now run multiple apps inside of 1 tomcat. <snip> Any other cool features like this in the JDK ? </snip> Just that super cool System.getProperties()
This is the same solution as was found previously in the following two bugs... http://issues.apache.org/bugzilla/show_bug.cgi?id=26372 http://issues.apache.org/bugzilla/show_bug.cgi?id=27371 The solution was originally (as far as I know) found here... http://marc.theaimsgroup.com/?t=109578393000004&r=1&w=2 It would have been nice to have recognized this information back in September '04 when Yoav posted references to the solution rather than having to re-figure it out independently in January '05 and finaly take action. In any case, I'm glad it is finally fixed! Jake
This issue is incorrectly closed as WON'T FIX even though the 5.5.8 changelog marks it as fixed. Please reclose it as fixed.
Oops, I can do this myself :)
*** Bug 36548 has been marked as a duplicate of this bug. ***