ThreadLocal内存泄漏怎么回事
ThreadLocal
本地线程,调用set方法往里面存的值,是每个线程互相隔离,互不影响的,每个线程都有一块存储ThreadLocal数据的地方叫做ThreadLocalMap,这个变量专门用于存储当前线程的map数据,调用ThreadLocal.set方法的时候,就是往这个ThreadLocalMap里面存储一个一个的entry,由key和value组成,key是当前的ThreadLocal,value是set()里面的值。
代码中常用到的ThreadLocal只是暴露出来,方便用于获取当前Thread对象内的ThreadLocalMap的工具类
ThreadLocal模型如下:

内存泄露
如果在线程池中使用ThreadLocal,会出现内存泄露的问题,因为当ThreadLocal对象使用完之后,应该要把设置的key,value,也就是Entry对象回收,但线程池中的线程不会回收,而线程对象是通过强引用指向ThreadLocalMap,ThreadLocalMap是通过强引用指向Entry对象,线程不被回收,Entry对象也就不会被回收,从而出现内存泄露
解决办法
在使用ThreadLocal对象以后,手动调用ThreadLocal的remove方法,手动清除Entry对象
常见用法
-
参数跨层传递,如果很深的方法,每个类内都需要一个变量,如果在方法签名上传来传去,会造成可读性变差,也不利于维护。
-
隔离线程,存储一些线程不安全的对象,如SimpleDateFormat
-
Spring中的事务管理器就是用的ThreadLocal
-
SpringMVC中的HttpSession,HttpRequest、HttpResponse、都是放在ThreadLocal中的,因为servlet是单例的,而springmvc允许在controller中通过@Autowired配置request,response以及RequestContext等实例对象,底层就是搭配ThreadLocal才能实现线程安全

浙公网安备 33010602011771号