tomcat-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Apache Wiki <wikidi...@apache.org>
Subject [Tomcat Wiki] Update of "MemoryLeakProtection" by SylvainLaurent
Date Sun, 06 Jun 2010 21:15:50 GMT
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.ThreadLocal@44676e3f]) and a value of type [test.leak.threadlocal.value.MyCounter]
(value [test.leak.threadlocal.value.MyCounter@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-unsubscribe@tomcat.apache.org
For additional commands, e-mail: dev-help@tomcat.apache.org


Mime
View raw message