按照网上图的来说是栈里 threadlocal 的强引用断开后,而这个线程一直存活的情况,value 不会释放 从而导致内存泄漏(这个理解没错吧)
ThreadLocal tl = new ThreadLocal();
tl.set(1)
do something;
//这边设置 null 断开强引用 应该会产生内存泄漏吧?
//但是实际开发 应该不会这么无聊 手动设置成 null 吧;
//所以 实际情况下 什么时候会产生内存泄漏 (排除这种 new ThreadLocal().set(1)的 骚操作)
tl = null;
System.gc();
1
szq8014 2020-05-12 18:08:13 +08:00
```tl = null; ```
这一行没有任何效果,ThreadLocal 这东西是跟线程绑定的,只要你不 remove 或者不把线程关掉,那你 set 的东西就一直在那里陪着线程。 想要泄漏就可以 set 一个 List 然后 list 一直往里加东西就可以了。 |
2
chendy 2020-05-12 18:08:39 +08:00
但是 ThreadLocal 本身还有个弱引用兜底,只要没有强应用就会被 gc 带走,所以可以说木有内存泄漏了
|
3
szq8014 2020-05-12 18:08:55 +08:00
具体见 java.lang.Thread#threadLocals
|
4
Uchiha0bito 2020-05-12 18:19:48 +08:00
每个线程都有一个 ThreadLocalMap,key 就是这个线程往哪些 ThreadLocal 存放了元素,value 就是对应存放的元素。key 泄漏可以由 jdk 解决,因为 key 引用是弱引用。但是 value 泄漏是没有解决的,需要用户每次使用完就移除,否则就一直在那儿
|
5
Uchiha0bito 2020-05-12 18:22:26 +08:00
所以 tl = null 这个不会导致泄漏,因为没有强引用存在的情况下 value 就被 gc 了。但是,如果是 t1.set(一个 User 对象),那这个 User 对象的强引用就一直被 ThreadLocalMap 存着了,不手动删掉就会泄漏
|
6
jinzhongyuan 2020-05-12 18:45:01 +08:00
@szq8014 这是内存溢出吧?
|
7
hangszhang 2020-05-12 22:55:29 +08:00
ThreadLocalMap 的 get 和 set 方法自己会清除数据,所以已经很难内存泄露了,但是最好还是养成用完 remove 习惯
|
8
szq8014 2020-05-13 08:58:20 +08:00
@jinzhongyuan 哈哈,是. 放了不删除就是泄露了,一直放了不管会溢出,2333
|
9
ica10888 2020-05-13 09:39:15 +08:00
Entry 是 ThreadLocal 的弱引用,非严格意义来说不会产生内存泄露。用 threadlocal 一般是在多个方法里面线程自己变量的存放,一般不讨论内存泄露的问题...
|