Dear Wiki user,

You have subscribed to a wiki page or wiki category on "Tomcat Wiki" for change 
notification.

The "MemoryLeakProtection" page has been changed by SylvainLaurent.
http://wiki.apache.org/tomcat/MemoryLeakProtection?action=diff&rev1=10&rev2=11

--------------------------------------------------

  
  = Summary matrix =
  ||'''Leak cause'''||'''Detected by tomcat'''||'''Fixed by 
tomcat'''||'''Possible enhancements'''||
- ||[[#customThreadLocal|Custom ThreadLocal class]]||>=6.0.24||>=6.0.24|| 
[[#48837|Detect child classloaders]], [[#48895|improve thread safety]] ||
- ||[[#webappClassInstanceAsThreadLocalValue|Webapp class instance as 
ThreadLocal value]]||>=6.0.24||>=6.0.24|| [[#48837|Detect child classloaders]], 
[[#48895|improve thread safety]] ||
+ ||[[#customThreadLocal|Custom ThreadLocal class]]||>=6.0.24||6.0.24-6.0.26 
but is unsafe. Made optional from 6.0.27|| [[#48837|Detect child 
classloaders]], [[#49159|BZ 49159]] ||
+ ||[[#webappClassInstanceAsThreadLocalValue|Webapp class instance as 
ThreadLocal value]]||>=6.0.24||6.0.24-6.0.26 but is unsafe. Made optional from 
6.0.27|| [[#48837|Detect child classloaders]], [[#49159|BZ 49159]] ||
- ||[[#webappClassInstanceAsThreadLocalIndirectValue|Webapp class instance 
indirectly held through a ThreadLocal value]]||no||no||Renew threads in the 
worker pool||
+ ||[[#webappClassInstanceAsThreadLocalIndirectValue|Webapp class instance 
indirectly held through a ThreadLocal value]]||no||no||[[#49159|Renew threads 
in the worker pool]]||
- ||[[#threadLocalPseudoLeak|ThreadLocal 
pseudo-leak]]||>=6.0.24||>=6.0.24||[[#48895|improve thread safety]]||
- ||[[#cclThreadSpawnedByWebApp|ContextClassLoader / Threads spawned by 
webapps]]||>=6.0.24||{{{TimerThread}}} are stopped. Other threads may be 
stopped if {{{clearReferencesStopThreads}}} is set to true on the Context 
||[[#48837|Detect child classloaders]], [[#48971|don't stop TimerThread by 
default]]||
- ||[[#cclThreadSpawnedByCommonClassLoader|ContextClassLoader / Threads spawned 
by classes loaded by the common classloader]]||>=6.0.24||{{{TimerThread}}} are 
stopped. Other threads may be stopped if {{{clearReferencesStopThreads}}} is 
set to true on the Context ||[[#48837|Detect child classloaders]], 
[[#48971|don't stop TimerThread by default]]||
+ ||[[#threadLocalPseudoLeak|ThreadLocal pseudo-leak]]||>=6.0.24||6.0.24-6.0.26 
but is unsafe. Made optional from 6.0.27||[[#49159|BZ 49159]]||
+ ||[[#cclThreadSpawnedByWebApp|ContextClassLoader / Threads spawned by 
webapps]]||>=6.0.24||In 6.0.24-6.0.26 {{{TimerThread}}} are stopped but it may 
lead to problems. Optional from 6.0.27 with the 
{{{clearReferencesStopTimerThreads}}} flag. Other threads may be stopped with 
the {{{clearReferencesStopThreads}}} flag, but it's unsafe. ||[[#48837|Detect 
child classloaders]], Fix the application to stop the thread when the 
application is stopped||
+ ||[[#cclThreadSpawnedByCommonClassLoader|ContextClassLoader / Threads spawned 
by classes loaded by the common classloader]]||>=6.0.24||In 6.0.24-6.0.26 
{{{TimerThread}}} are stopped but it may lead to problems. Optional from 6.0.27 
with the {{{clearReferencesStopTimerThreads}}} flag. Other threads may be 
stopped with the {{{clearReferencesStopThreads}}} flag, but it's unsafe. 
||[[#48837|Detect child classloaders]], fix the offending code (set the correct 
CCL when spawning the thread)||
  ||[[#cclThreadSpawnedByJRE|ContextClassLoader / Threads spawned by JRE 
classes]]|| no || >=6.0.24 pre-spawns some known offenders || ||
  ||[[#staticClassVariables|static class variables]]|| no ||> 6.0.? || ||
  ||[[#LogFactory|LogFactory]]||  ||> 6.0.? || ||
@@ -84, +84 @@

  
  Hopefully tomcat 6.0.24 can detect the leak when the application is stopped: 
each Thread in the JVM is examined, and the internal structures of the Thread 
and {{{ThreadLocal}}} classes are introspected to see if either the 
{{{ThreadLocal}}} instance or the value bound to it were loaded by the 
{{{WebAppClassLoader}}} of the application being stopped.
  
- In this particular case, the leak is detected, a message is logged and 
internal structures of the JDK ({{{ThreadLocalMap}}}) are modified to remove 
the reference to the {{{ThreadLocal}}} instance.
+ In this particular case, the leak is detected and a message is logged. Tomcat 
6.0.24 to 6.0.26 modify internal structures of the JDK ({{{ThreadLocalMap}}}) 
to remove the reference to the {{{ThreadLocal}}} instance, but this is unsafe 
(see [[#48895]]) so that it became optional and disabled by default from 6.0.27.
  
  {{{
  Mar 16, 2010 11:47:24 PM org.apache.catalina.loader.WebappClassLoader 
clearThreadLocalMap
@@ -145, +145 @@

  
  If the servlet is invoked at least once, the webapp classloader would not be 
GCed when the app is stopped: since the classloader of {{{ThreadScopedHolder}}} 
is the common classloader, it remains forever which is as expected. But its 
{{{ThreadLocal}}} instance has a value bound to it (for the non-terminated 
thread(s) that served the sevlet), which is an instance of a class loaded by 
the webapp classloader...
  
- Here again, tomcat 6.0.24 will detect and fix the leak by removing this 
{{{ThreadLocal}}} reference from each Thread.
+ Here again, tomcat >=6.0.24 will detect the leak :
  {{{
  Mar 17, 2010 10:23:13 PM org.apache.catalina.loader.WebappClassLoader 
clearThreadLocalMap
  SEVERE: A web application created a ThreadLocal with key of type 
[java.lang.ThreadLocal] (value [java.lang.threadlo...@44676e3f]) and a value of 
type [test.leak.threadlocal.value.MyCounter] (value 
[test.leak.threadlocal.value.mycoun...@62770d2e]) but failed to remove it when 
the web application was stopped. To prevent a memory leak, the ThreadLocal has 
been forcibly removed.
@@ -229, +229 @@

  
  If many threads were used to serve our leaking webapp, but after we stop it 
only a couple of threads are enough to serve other webapps, one could have some 
threads that are no longer used, waiting for some work. Since those threads are 
blocked, they have no interaction with their {{{ThreadLocalMap}}} (i.e. there's 
no {{{ThreadLocal}}} value bound to them or removed), so that there's no 
opportunity to {{{expungeStaleEntries()}}}.
  
- Tomcat 6.0.24 "speeds up" the removal of stale entries (and thus fixes the 
pseudo-leak), by calling {{{expungeStaleEntries()}}} for each thread that has 
some stale entries.
+ Tomcat 6.0.24-6.0.26 "speeds up" the removal of stale entries (and thus fixes 
the pseudo-leak), by calling {{{expungeStaleEntries()}}} for each thread that 
has some stale entries. Since it's not thread-safe, it has been made optional 
and disabled by default from 6.0.27.
  
  == Threads ContextClassLoader ==
  <<Anchor(cclThreadSpawnedByWebApp)>>
@@ -352, +352 @@

  SEVERE: A web application appears to have started a TimerThread named 
[Timer-0] via the java.util.Timer API but has failed to stop it. To prevent a 
memory leak, the timer (and hence the associated thread) has been forcibly 
cancelled. 
  }}}
  
+ So the leak is fixed, but unfortunately there's a side effect : [[#48971|it 
broke webapp B eviction timer]]. That's why stopping {{{TimerThread}}} has been 
made optional from 6.0.27.
- So the leak is fixed, but unfortunately there's a side effect : [[#48971|it 
broke webapp B eviction timer]].
- 
- Note: as of 6.0.24, by default tomcat stops threads of class 
{{{java.util.TimerThread}}} whose context classloader is the 
{{{WebAppClassLoader}}} of the app being stopped. It does not stop other 
threads, it only warns about them. It can try to stop them if the 
{{{clearReferencesStopThreads}}} option of the standard context is set to true.
  
  <<Anchor(cclThreadSpawnedByJRE)>>
  === Threads spawned by JRE classes ===
@@ -365, +363 @@

  
  == Child classloaders ==
  
- When an app is stopped, Tomcat 6.0.24 detects leaks caused by 
{{{ThreadLocal}}}s and Threads context classloader only by checking for the 
current {{{WebAppClassLoader}}}. If a child classloader is involved, the leak 
is not detected. That should be [[#48837|improved in a future release]].
+ When an app is stopped, Tomcat 6.0.24 and later detect leaks caused by 
{{{ThreadLocal}}}s and Threads context classloader only by checking for the 
current {{{WebAppClassLoader}}}. If a child classloader is involved, the leak 
is not detected. That should be [[#48837|improved in a future release]].
  
  <<Anchor(staticClassVariables)>>
  == static class variables ==
@@ -406, +404 @@

   * 
<<Anchor(48837)>>[[https://issues.apache.org/bugzilla/show_bug.cgi?id=48837|48837]]
 - Memory leaks protection does not cure leaks triggered by JSP pages code
   * 
<<Anchor(48895)>>[[https://issues.apache.org/bugzilla/show_bug.cgi?id=48895|48895]]
 - !WebAppClassLoader.clearThreadLocalMap() concurrency issues
   * 
<<Anchor(48971)>>[[https://issues.apache.org/bugzilla/show_bug.cgi?id=48971|48971]]
 - memory leak protection : stopping !TimerThreads should be optional and 
disabled by default
+  * <<Anchor(49159)>>[[https://issues.apache.org/bugzilla/show_bug.cgi?id= 
49159|49159]] - Improve ThreadLocal memory leak clean-up
+  * [[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4957990|Sun bug 
4957990]] - In some cases the Server JVM fails to collect classloaders. 
According to [[http://bugs.sun.com/bugdatabase/view_bug.do?bug_id=4957990|this 
page]] it should have been fixed with java 6u16 but actually it was not. It 
seems to be fixed with 6u21 (documented 
[[http://download.java.net/jdk6/6u21/promoted/b03/changes/JDK6u21.list.html|here]]
 and verified by the author of this wiki page).
  

---------------------------------------------------------------------
To unsubscribe, e-mail: dev-unsubscr...@tomcat.apache.org
For additional commands, e-mail: dev-h...@tomcat.apache.org

Reply via email to