Versions Compared

Key

  • This line was added.
  • This line was removed.
  • Formatting was changed.

...

Leak cause

Detected by tomcat

Fixed by tomcat

Possible enhancements

Custom ThreadLocal class

>=6.0.246

>= 7.0.24-6.0.26 but is unsafe. Made optional from 6 .0.27

  Detect child classloaders, BZ 49159

Webapp class instance as ThreadLocal value

>=6.0.246

>= 7.0.24-6 .0.26 but is unsafe. Made optional from 6.0.27

  Detect child classloaders, BZ 49159

Webapp class instance indirectly held through a ThreadLocal value

no

no

>= 7.0.6

 Renew threads in the worker pool

ThreadLocal pseudo-leak

>=6.0.246.0.24-6

>= 7.0.26 but is unsafe. Made optional from 6 .0.27

 BZ 49159

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.

Detect child classloaders, Fix the application to stop the thread when the application is stopped

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.

Detect child classloaders, fix Fix the offending code (set the correct CCL when spawning the thread)

ContextClassLoader / Threads spawned by JRE classes

no

>=6.0.24 pre-spawns some known offenders

 

static class variables

no

> 6.0.? . Disabled by default with tomcat 7

 

LogFactory

 

> 6.0.?

 

JDBC driver registration

> 6.0.?

> 6.0.?

 

RMI Target

 

> 6.0.?

 

...

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 6from 6.0.27. Starting with Tomcat 7.0.276, the threads of the pool are renewed so that the leak is safely fixed.

No Format
Mar 16, 2010 11:47:24 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: A web application created a ThreadLocal with key of type [test.MyThreadLocal] (value [test.MyThreadLocal@4dbb9a58]) and a value of type [test.MyCounter] (value [test.MyCounter@57922f46]) but failed to remove it when the web application was stopped. To prevent a memory leak, the ThreadLocal has been forcibly removed.

Note: this particular leak was actually already cured by previous versions of tomcat 6, because static references of classes loaded by the webappclassloader are nullified (see later).

...

We have more or less the same kind of leak as the previous one, but this time tomcat 6.0.24 does not detect the leak when stopping the application (and does not fix it). The problem is that when it inspects the entries of ThreadLocalMap, it checks whether either the key or the value is an instance of a class loaded by the webapp classloader. Here the key is an instance of ThreadLocal, and the value is an instance of java.util.ArrayList.

...

But it does not give any clue about what caused the leak, we would need to make a heapdump and analyse it with some tool like Eclipse MAT.

Tomcat 7.0.6 and later fix this leak by renewing threads in the pool.

Anchor
threadLocalPseudoLeak
threadLocalPseudoLeak

...

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.276.0.27.

Tomcat 7.0.6 and later fix the problem by renewing threads in the pool.

Threads ContextClassLoader

...

Instead of trying to stop such threads, tomcat prefers to force the creation of such threads when the container is started, before webapps are started. The JreMemoryLeakPreventionListener does it for a few known offenders in the JRE.

Child classloaders

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 improved in a future releasein the JRE.

Anchor
staticClassVariables
staticClassVariables

...

  • Anchor
    48837
    48837
    48837 - Memory leaks protection does not cure leaks triggered by JSP pages code
  • Anchor
    49159
    49159
    49159 - Improve ThreadLocal memory leak clean-up
  • Sun bug 4957990 - In some cases the Server JVM fails to collect classloaders. According to this page it should have been fixed with java 6u16 but actually it was not. It seems to be fixed with 6u21 (documented here and verified by the author of this wiki page).
  • Sun bug 6916498 - An exception can keep a classloader in memory if the stack trace that was recorded when it was created contains a reference to one of its classes. Some fixes have been made in tomcat (see BZ 50460), but some library or JRE code may still create a leak that is undetected by tools because of this JVM bug.

...

CategoryFAQ