ThreadLocal可能存在的问题

ThreadLocal对象内部有一个ThreadLocalMap类型的成员变量,这个Map的生命周期和线程本身是绑定的,只要线程不销毁,这个Map就会一直存在。

ThredLocalMap存储数据用的Entry继承了WeakReference,它的结构是这样的: key是对ThreadLocal对象的弱引用,而value是我们存入的值,它是强引用。

内存泄漏问题

当一个ThreadLocal对象在外部没有了强引用(比如方法执行结束),下一次GC发生的时候,由于Entry的key是弱引用,所以ThreadLocal对象会被回收。 这时,ThreadLocalMap中就会出现key为Null的Entry,这个Entry的value仍然是强引用的,这就导致了内存泄漏。只要线程不结束,ThreadLocalMap就会一直持有这个值,无法被回收,Entry会一直持有这个value的强引用,导致value无法被垃圾回收。如果线程是从线程池中复用的,那么这个线程的生命周期会很长,这些value就会极少称多,最终导致内存泄漏。

因此,为了防止ThreadLocal内存泄漏,在使用完ThreadLocal之后,必须在代码中调用ThreadLocal的remove()方法来清除当前线程中的ThreadLocal变量。


相关内容

0%