简而言之 - tomcat 使用线程池,因此线程被重用。一些图书馆使用ThreadLocal
变量,但不要清理它们(使用.remove()
),所以实际上它们将“脏”线程返回到池中。
Tomcat 具有在关闭时检测这些事情并清理线程局部变量的新功能。但这意味着线程在整个执行过程中是“脏的”。
我能做的就是实施一个Filter
,并在请求完成后(并且线程返回到池中),清除所有ThreadLocal
s,使用来自 tomcat 的代码 http://svn.apache.org/repos/asf/tomcat/tc7.0.x/tags/TOMCAT_7_0_8/java/org/apache/catalina/loader/WebappClassLoader.java(那里的方法被称为checkThreadLocalsForLeaks
).
问题是,值得吗?两个优点:
- 防止内存泄漏
- 防止库的不确定行为,假设线程是“新鲜的”
One con:
- 该解决方案使用反射,因此可能会很慢。所有反射数据(
Field
s) 当然会被缓存,但仍然如此。
另一种选择是将问题报告给不清理线程局部变量的库。
我会通过向库开发人员报告问题的方式进行处理,原因有两个:
- 它将帮助其他想要使用相同库但缺乏技能/时间来发现如此可怕的内存泄漏的人。
- 帮助库的开发人员构建更好的产品。
老实说,我以前从未见过这种类型的错误,我认为这是一个例外,而不是我们应该警惕的事情,因为它经常发生。您能分享一下您在哪个库上看到过这种行为吗?
附带说明一下,如果仍然附加 ThreadLocal 变量,我不介意在开发/测试环境中启用该过滤器并记录严重错误。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)