使用ThreadLocal的库可能会导致Tomcat中的内存泄漏

时间:2015-09-02 17:26:28

标签: java tomcat grails memory-leaks

我正在使用Box.com Java SDK,该库执行以下ThreadLocal:

private static final ThreadLocal<DateFormat> THREAD_LOCAL_DATE_FORMAT =
        new ThreadLocal<DateFormat>() {
    @Override
    protected DateFormat initialValue() {
        return new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ssZ");
    }
};

但是,我相信这是我的tomcat连接池问题的原因。特别是因为据报道后续泄漏会影响HibernatePersistenceContextInterceptor。

  

SEVERE:Web应用程序[]使用[com.box.sdk.BoxDateFormat $ 1]类型的键(值[com.box.sdk.BoxDateFormat$1@275ab696])创建了一个ThreadLocal,其值为[java。 text.Simple   DateFormat](值[java.text.SimpleDateFormat@faabb360])但在Web应用程序停止时无法将其删除。线程将随着时间的推移而更新以试图避免专业人士   bable内存泄漏。

如果没有重写大部分库,我有办法处理这种情况吗?

1 个答案:

答案 0 :(得分:2)

消息告诉您Tomcat将替换线程以清除这些孤立的ThreadLocal值。因此,虽然不能保证防止出现问题,但Tomcat正试图减轻bug的影响。

通常,这可能是一个问题,因为当弱引用的ThreadLocal实例被垃圾收集时,线程映射中的条目可以保留一段时间,从而阻止值,它的类和它的类加载器来自被垃圾收集。但是,由于此情况下的值(DateFormat)来自引导加载程序,因此无论如何都不会卸载它,并且不应该是一个问题。

要在应用程序关闭时清除这些孤儿,您必须使用反射挖掘Thread的内部。听起来很乱!

我首先会寻找更有力的证据来归咎于你的连接池问题。例如,您的连接池中是否存在由Tomcat替换请求线程而暴露的错误?也许这个bug更容易修复自己。