是否值得清理过滤器中的线程Local来解决与线程池相关的问题?

2022-09-04 04:12:00

简而言之 - tomcat使用线程池,因此线程被重用。一些库使用变量,但不清理它们(使用),所以实际上它们将“脏”线程返回到池中。ThreadLocal.remove()

Tomcat 具有在关机时检测这些内容以及清理线程局部变量的新功能。但这意味着线程在整个执行过程中是“脏的”。

我能做的是实现一个,并在请求完成后(线程返回到池中),使用tomcat中的代码(那里的方法称为)清理所有s。FilterThreadLocalcheckThreadLocalsForLeaks

问题是,这值得吗?两个优点:

  • 防止内存泄漏
  • 防止库的不确定行为,这些行为假设线程是“新鲜的”

一个缺点:

  • 该解决方案使用反射,因此可能会很慢。当然,所有反射数据都将被缓存,但仍然如此。Field

另一种选择是将问题报告给不清理其线程局部变量的库。


答案 1

我会通过向库开发人员报告问题的方法,原因有2个:

  • 它将帮助其他想要使用同一库的人,但缺乏技能/时间来找到如此可怕的内存泄漏。
  • 帮助库的开发者构建更好的产品。

老实说,我以前从未见过这种类型的错误,我认为这是一个例外,而不是我们应该经常发生的事情。你能分享一下你见过这种行为的图书馆吗?

作为旁注,我不介意在开发/测试环境中启用该过滤器,并在仍然附加ThreadLocal变量时记录严重错误。


答案 2

从理论上讲,这似乎是一个好主意。但是,我可以看到您可能不想这样做的某些情况。例如,一些与xml相关的技术具有一些不平凡的设置成本(例如设置DocumentBuilders和Transformers)。如果您在 Web 应用程序中执行了大量操作,则在 ThreadLocals 中缓存这些实例可能是有意义的(因为这些实用程序通常不是线程安全的)。在这种情况下,您可能不希望在请求之间清理这些内容。