Clojure Web 应用程序中的内存泄漏
我在 Clojure 中创建了一个 Web 应用程序,将其打包为 WAR,并将其部署在 Tomcat 之上。它按我的预期工作,但是当我关闭 Tomcat 时,我看到许多异常,如下所示:
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 memory leak.
我知道 clojure 所做的一些事情有时可能会比 Java 垃圾收集器领先一些。我的战争确实有一个 ServletContextListener 启动一些后台线程,但我看不出为什么这些线程不应该在上下文取消部署时优雅地终止(毕竟它们不是守护线程)。
我是否应该使用更好/不同的方式来启动对 Tomcat 更友好的线程?现在我只是通过调用 (future (loop ...
.
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 memory 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 ...
.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
显然 Tomcat 有 内存泄漏保护 - 查看链接。
我不认为这实际上是内存泄漏,更有可能的是 Tomcat 热衷于报告某些线程/threadlocal 尚未正确关闭/释放的事实。
该警告很烦人,但这并不是真正的致命问题,因为一旦 JVM 关闭,所有线程本地内存都会被释放。
一般来说,使用 (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.