Bug 26135

Summary: Tomcat 5.0.16 leaks memory when a webapp is reloaded or stopped/started
Product: Tomcat 5 Reporter: Joe Porcheddu <jporche>
Component: CatalinaAssignee: Tomcat Developers Mailing List <dev>
Severity: normal CC: james.norman, jqs, rflament
Priority: P3    
Version: 5.0.16   
Target Milestone: ---   
Hardware: PC   
OS: Windows XP   

Description Joe Porcheddu 2004-01-14 17:27:47 UTC
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.
Comment 1 Remy Maucherat 2004-01-14 17:34:10 UTC
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).
Comment 2 Jeffrey Steele 2004-01-28 23:54:21 UTC
I believe this is a bug within Tomcat...

Here is a way to replicate it:

Use the Struts blank war.
Available here:

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...
Comment 3 Remy Maucherat 2004-01-29 08:35:20 UTC
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
Comment 4 Remy Maucherat 2004-12-15 00:40:43 UTC
*** Bug 32709 has been marked as a duplicate of this bug. ***
Comment 5 James Norman 2004-12-15 17:46:44 UTC
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.

James Norman
Comment 6 Tobias L 2005-01-25 13:21:02 UTC
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 
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.
Comment 7 Remy Maucherat 2005-01-25 14:13:38 UTC
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.
Comment 8 James Norman 2005-01-26 22:31:57 UTC
That got it.  Thanks to all who resolved this, we can now run multiple apps
inside of 1 tomcat.

  Any other cool features like this in the JDK ?

Just that super cool System.getProperties()

Comment 9 Jacob Kjome 2005-02-05 19:05:04 UTC
This is the same solution as was found previously in the following two bugs...

The solution was originally (as far as I know) found here...

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!

Comment 10 Gili 2005-08-22 17:57:58 UTC
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.
Comment 11 Gili 2005-08-22 18:18:42 UTC
Oops, I can do this myself :)
Comment 12 Robert Longson 2005-10-18 11:24:59 UTC
*** Bug 36548 has been marked as a duplicate of this bug. ***