I have been getting the ThreadLocal cleanup warning messages appearing in the Tomcat log for some time now. I finally got around to investigating these and cleaning it all up. Most of the ThreadLocals I removed, because they were being abused. However, some needed to hang around, so I used them more carefully.
Now, at the end of each request, I am calling: threadLocalInstance.set(null); threadLocalInstance.remove(); And most of the messages went away. However, a few were still sticking around. I wanted to track them down, but that’s hard since ThreadLocals don’t have names. So, I replaced all instances of ThreadLocal in my project with Spring Framework’s NamedThreadLocal (which simply overrides toString() to provide better debugging), and here is the resulting log: Feb 22, 2012 6:21:23 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: The web application [/xxx] created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [GridDataHandler:reminders]) and a value of type [MyPackage.MyClass] (value [MyPackage.MyClass @1068452]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. Feb 22, 2012 6:21:23 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: The web application [/xxx] created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [GridDataHandler:accidentinvestigation]) and a value of type [MyPackage.MyClass] (value [MyPackage.MyClass @d92404]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. Feb 22, 2012 6:21:23 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: The web application [/xxx] created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [GridDataHandler:encounterlisting]) and a value of type [MyPackage.MyClass] (value [MyPackage.MyClass @1cbad1a]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. Feb 22, 2012 6:21:23 PM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap SEVERE: The web application [/xxx] created a ThreadLocal with key of type [org.springframework.core.NamedThreadLocal] (value [GridDataHandler:reminders]) and a value of type [MyPackage.MyClass] (value [MyPackage.MyClass @d19d73]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak. I’m still getting these four messages, and I can’t seem to get them to go away. But I have tracked down these specific instances and I *am* calling set(null) and remove() on these instances. Is something about the Tomcat code somehow locating “phantom” references to ThreadLocals that have actually been removed and ARE really eligible for GC, or am I really just not always clearing those ThreadLocals and I just still haven’t tracked down the source? Thanks, Nick -- *Nick Williams |* Senior Software Developer *UL PureSafety* Health & Safety Software Solutions Toll Free: 888.202.3016 x 177 | Direct: 615.277.3177 | Fax: 615.367.3887 730 Cool Springs Blvd, Suite 400 | Franklin, TN 37067 | www.puresafety.com | www.ul.com ------------------------------ *UL acquired PureSafety on December 6, 2011. Learn More.<http://www.puresafety.com/public/knowledge-exchange/news/2011/12/06/ul-expands-occupational-health-safety-presence-training-capabilit> *