ThreadLocal内存泄漏怎么回事

ThreadLocal

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

内存泄露

如果在线程池中使用ThreadLocal,会出现内存泄露的问题,因为当ThreadLocal对象使用完之后,应该要把设置的key,value,也就是Entry对象回收,但线程池中的线程不会回收,而线程对象是通过强引用指向ThreadLocalMap,ThreadLocalMap是通过强引用指向Entry对象,线程不被回收,Entry对象也就不会被回收,从而出现内存泄露

解决办法

在使用ThreadLocal对象以后,手动调用ThreadLocal的remove方法,手动清除Entry对象

常见用法

  1. 参数跨层传递,如果很深的方法,每个类内都需要一个变量,如果在方法签名上传来传去,会造成可读性变差,也不利于维护。

  2. 隔离线程,存储一些线程不安全的对象,如SimpleDateFormat

  3. Spring中的事务管理器就是用的ThreadLocal

  4. SpringMVC中的HttpSession,HttpRequest、HttpResponse、都是放在ThreadLocal中的,因为servlet是单例的,而springmvc允许在controller中通过@Autowired配置request,response以及RequestContext等实例对象,底层就是搭配ThreadLocal才能实现线程安全

posted @ 2024-10-17 18:23  iiiiiiiivan  阅读(18)  评论(0)    收藏  举报