Memory leak in Clojure web application
I've created a web application in Clojure, packaged it as a WAR, and deployed it on top of Tomcat. It works as I expect, but when I go to shut down Tomcat, I see many exceptions like the following:
SEVERE: The web application [] created a ThreadLocal with key of type
[java.lang.ThreadLocal] (value [java.lang.ThreadLocal@fc5408]) and a value of type [clojure.lang.LockingTransaction] (value [clojure.lang.LockingTransaction@12db7c]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 17, 2011 4:19:48 AM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [] created a ThreadLocal with key of type [null] (value [clojure.lang.Var$1@11de914]) and a value of type [clojure.lang.Var.Frame] (value [clojure.lang.Var$Frame@7c28c]) but failed to remove it when the web application was stopped. This is very likely to create a memory leak.
Mar 17, 2011 4:19:48 AM org.apache.catalina.loader.WebappClassLoader clearThreadLocalMap
SEVERE: The web application [] created a ThreadLocal with key of type [null] (value [clojure.lang.Var$1@11de914]) and a value of type [clojure.lang.Var.Frame] (value [clojure.lang.Var$Frame@17588d5]) but failed to remove it when the web application was stopped. This is very likely to create a memor开发者_C百科y leak.
I understand there are some things clojure does that may get a little ahead of the Java garbage collector at times. My war does have a ServletContextListener that starts a few background threads, but I see no reason why these shouldn't just be gracefully terminated (they aren't daemon threads, after all) when the context undeploys.
Is there perhaps a better/different way I should be using to start my threads that's more Tomcat-friendly? Right now I am just starting them by calling (future (loop ...
.
Apparently Tomcat has memory leak protection - check out the link.
I don't think it is actually a memory leak, it's more likely that Tomcat is being zealous about reporting the fact that certain threads/threadlocal haven't been properly shut down/released.
The warning is annoying, but it's not really a fatal issue as all threadlocal memory will be released anyway as soon as the JVM shuts down.
Starting your threads with (future (loop ...)) is fine in general, but you should ensure that they actually exit at the right moment. This could mean having something like an "is-shutting-down?" atom that you can check on each loop. You might find that this removes the warning.
精彩评论