ThreadLocal尾篇:ThreadLocal内存泄漏到底因为啥

简介: ThreadLocal尾篇:ThreadLocal内存泄漏到底因为啥

最近看ThreadLocal内存泄漏这块,网上说法很多。呼声最多的是因为弱引用导致的内存泄漏。


为啥内存泄漏


image.png


1.ThreadLocal什么情况下被回收

ThreadLocalThreadLocalMap中是以一个弱引用身份被Entry中的Key引用,当GC发生时,ThreadLocal会不会被回收?

这里就用到引用的知识点了。 在java的四种引用讲过。当一个对象被强引用指向时(这里指可达)。垃圾回收器不会回收他。

例如

ThreadLocal threadlocal1 = new ThreadLocal();
threadlocal1.set("测试");

ThreadLocal对象此时有两种索引指向的。

  • 强引用:threadlocal1对应图中【1】
  • 弱引用:Key(WeakReference(threadlocal1))对应图中的【2】

所以GC发生时,堆内ThreadLocal对象不会被回收。

但是当我们把threadlocal1 =null;断开强引用时,此时ThreadLocal对象只有一个弱引用,那么GC发生时,ThreadLocal对象被回收了,Entry变成了一个key为null的Entry。也叫脏Entry

特点是:

  • key为null,value不能被应用程序访问到,因为我们已经没有引用到他的引用了
  • Thread Ref -> Thread -> ThreaLocalMap -> Entry -> value链存在,当前线程迟迟不结束(例如线程池),但不能被使用,成了脏数据,造成了内存泄漏。

看上去好像真是软引用造成的内存泄漏。


2.为啥用弱引用

那换做强引用分析:ThreadLocal对象被两个强引用指向

  • 强引用: threadlocal1
  • 强引用: Entry.key

当我们断开程序中的强引用 threadlocal1时。ThreadLocal对象仍然被强引用Entry.key指向,不会回收,这就造成,ThreadLocal对象与 value都成为了脏数据。


对比这两种情况:不管软引用还是强引用,都可能出现内存泄漏问题,弱引用反而将内存泄漏的程度降低

利用弱引用的Entry会有key为null这个特征,可以识别哪些是不用的数据,进行清理操作,弱引用 反而提高了ThreadLocal的安全性。

事实上当调用ThreadLocalget(),set(),reomve()方法,都会清除掉线程ThreadLocalMap中所有Entry中Key为null的Value,并将整个Entry设置为null,利于下次内存回收。

3.泄漏的真正原因

所以:ThreadLocal内存泄漏的真正原因:

  1. ThreadLocalMap的生命周期跟Thread一样长,如果线程池不退,例如线程池,可能造成内存泄漏
  2. 使用完没有及时清理,不再调用get()、set()、remove()对脏Entry进行清理

这才是造成内存泄漏的真正原因。


总结:


使用完及时remove,才是最正宗的使用方式

如有错误,请告知,共同学习。


相关文章
|
7月前
|
缓存 监控 Java
ThreadLocal 源码解析get(),set(), remove()用不好容易内存泄漏
ThreadLocal 源码解析get(),set(), remove()用不好容易内存泄漏
83 1
|
5月前
|
安全 Java
多线程线程安全问题之避免ThreadLocal的内存泄漏,如何解决
多线程线程安全问题之避免ThreadLocal的内存泄漏,如何解决
|
5月前
|
存储 缓存 Java
Java面试题:解释Java中的内存屏障的作用,解释Java中的线程局部变量(ThreadLocal)的作用和使用场景,解释Java中的锁优化,并讨论乐观锁和悲观锁的区别
Java面试题:解释Java中的内存屏障的作用,解释Java中的线程局部变量(ThreadLocal)的作用和使用场景,解释Java中的锁优化,并讨论乐观锁和悲观锁的区别
54 0
|
5月前
|
并行计算 算法 安全
Java面试题:解释Java内存模型的内存屏障,并讨论其对多线程并发的影响,解释Java中的线程局部变量(ThreadLocal)的工作原理,解释Java中的ForkJoinPool的工作原理
Java面试题:解释Java内存模型的内存屏障,并讨论其对多线程并发的影响,解释Java中的线程局部变量(ThreadLocal)的工作原理,解释Java中的ForkJoinPool的工作原理
42 0
|
5月前
|
Java 数据库连接
Java面试题:Java内存模型中的happens-before关系,Java中的ThreadLocal是如何工作的?Java中的CountDownLatch和CyclicBarrier的区别?
Java面试题:Java内存模型中的happens-before关系,Java中的ThreadLocal是如何工作的?Java中的CountDownLatch和CyclicBarrier的区别?
40 0
|
7月前
|
存储 Java 数据挖掘
来聊聊ThreadLocal内存泄露分析
来聊聊ThreadLocal内存泄露分析
189 0
|
存储 Java 应用服务中间件
百度搜索:蓝易云【导致JVM内存泄露的ThreadLocal详解?】
总之,合理使用ThreadLocal,并在不需要时及时清理,可以避免ThreadLocal内存泄露问题,确保应用程序的性能和内存使用的稳定性。
62 0
|
机器学习/深度学习 安全 Java
从源码深入详解ThreadLocal内存泄漏问题
从源码深入详解ThreadLocal内存泄漏问题
171 0
表妹和我纠结,线上系统因为一个ThreadLocal直接内存飙升
大家对于ThreadLocal这一个都应该听说过的吧,不知道大家对于这个掌握的怎么样了已经 这不,我那爱学习的表妹不知道又从哪里听来了这个技术点,回家就得意洋洋地给我说,表哥,我今天又学会了一个技术点ThreadLocal
|
存储 Java
【ThreadLocal的内存泄露问题】
【ThreadLocal的内存泄露问题】