为什么需要在拦截器删除threadLocal中的数据

threadLocal的应用主要是对一个线程内的变量进行传递不会创建对象,比如在全局日志里的应用,数据库连接池的应用也是。但是threadLocal也存在一个问题。

第一:因为在实际中的使用的时候,我们使用的tomcat的线程池时候,如果使用完不删除threadLocal里面数据,会导致数据可能在下次请求时,被其他线程可见。

第二:ThreadLocal底层结构,每个thread中都存在一个map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例.

private void set(ThreadLocal<?> key, Object value) {} 这是ThreadLocalMap,key是ThreadLocal的ThreadLocal里面有个原子类,但是是用static修饰的,也就是说在类加载时,被赋值。

ThreadLocal导致内存泄露的根源

首先需要明确一点:ThreadLocal本身的设计是不会导致内存泄露的,原因更多是使用不当导致的!

ThreadLocalMap对象被Thread对象所持有,当线程退出时,Thread类执行清理操作,比如清理ThreadLocalMap;否则该ThreadLocalMap对象的引用并不会被回收。

根源:由于Entry的key弱引用特性(见注意),当每次GC时JVM会主动将无用的弱引用回收掉,因此当ThreadLocal外部没有强引用依赖时,就会被自动回收,这样就可能造成当ThreadLocal被回收时,相当于将Map中的key设置为null,但问题是该key对应的entry和value并不会主动被GC回收,

当Entry和value未被主动回收时,除非当前线程死亡,否则线程对于Entry的强引用会一直存在,从而导致内存泄露

建议: 当希望回收对象,最好使用ThreadLocal.remove()方法将该变量主动移除,告知JVM执行GC回收

注意: ThreadLocal本身不是弱引用的,Entry继承了WeakReference,同时Entry又将自身的key封装成弱引用,所有真正的弱引用是Entry的key,只不过恰好Entry的key是ThreadLocal。

直接用这个创建,最后在删除即可。

原博文:https://blog.csdn.net/qq_32296307/article/details/117408759

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值