博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ThreadLocal可能引起的内存泄露
阅读量:6656 次
发布时间:2019-06-25

本文共 949 字,大约阅读时间需要 3 分钟。

hot3.png

  threadlocal里面使用了一个存在弱引用的map,当释放掉threadlocal的强引用以后,map里面的value却没有被回收.而这块value永远不会被访问到了. 所以存在着内存泄露. 最好的做法是将调用threadlocal的remove方法.

  在threadlocal的生命周期中,都存在这些引用. 看下图: 实线代表强引用,虚线代表弱引用.

  

  每个thread中都存在一个map, map的类型是ThreadLocal.ThreadLocalMap. Map中的key为一个threadlocal实例. 这个Map的确使用了弱引用,不过弱引用只是针对key. 每个key都弱引用指向threadlocal. 当把threadlocal实例置为null以后,没有任何强引用指向threadlocal实例,所以threadlocal将会被gc回收. 但是,我们的value却不能回收,因为存在一条从current thread连接过来的强引用. 只有当前thread结束以后, current thread就不会存在栈中,强引用断开, Current Thread, Map, value将全部被GC回收.

  所以得出一个结论就是只要这个线程对象被gc回收,就不会出现内存泄露,但在threadLocal设为null和线程结束这段时间不会被回收的,就发生了我们认为的内存泄露。其实这是一个对概念理解的不一致,也没什么好争论的。最要命的是线程对象不被回收的情况,这就发生了真正意义上的内存泄露。比如使用线程池的时候,线程结束是不会销毁的,会再次使用的。就可能出现内存泄露。  

  PS.Java为了最小化减少内存泄露的可能性和影响,在ThreadLocal的get,set的时候都会清除线程Map里所有key为null的value。所以最怕的情况就是,threadLocal对象设null了,开始发生“内存泄露”,然后使用线程池,这个线程结束,线程放回线程池中不销毁,这个线程一直不被使用,或者分配使用了又不再调用get,set方法,那么这个期间就会发生真正的内存泄露。

转载于:https://my.oschina.net/u/658658/blog/1830812

你可能感兴趣的文章
解密FFmpeg播放状态控制内幕
查看>>
我的友情链接
查看>>
90、MPLS基础配置实验
查看>>
51cto博客 存在csrf漏洞
查看>>
我的友情链接
查看>>
我的友情链接
查看>>
路由器的密码恢复
查看>>
使用Hystrix守护应用(3)
查看>>
mysql数据库show processlist查看当前连接数及状态,show status查看所有状态
查看>>
收集了一些linux的命令
查看>>
Scenario 6 –HP C7000 Virtual Connect FlexFabric SUS with A/A Uplinks, 8
查看>>
Java 框架新贵入驻 TechEmpower Framework Benchmark
查看>>
CentOS6.3 64位安装wine出错,牛人帮帮忙
查看>>
国内的Maven服务器
查看>>
C# winform DataGridView 的18种常见属性
查看>>
MySQL存储过程
查看>>
ANTLR Reference书摘
查看>>
我的友情链接
查看>>
Ubuntu Mate:扩展存储到整张SD卡
查看>>
es学习5-slowlog
查看>>