threadlocal 到底什么情况下会内存泄漏?

2020-05-12 17:51:34 +08:00
 90928yao

按照网上图的来说是栈里 threadlocal 的强引用断开后,而这个线程一直存活的情况,value 不会释放 从而导致内存泄漏(这个理解没错吧)

ThreadLocal tl = new ThreadLocal();
tl.set(1)
do something;
//这边设置 null 断开强引用 应该会产生内存泄漏吧?
//但是实际开发 应该不会这么无聊 手动设置成 null 吧;
//所以 实际情况下 什么时候会产生内存泄漏 (排除这种 new ThreadLocal().set(1)的 骚操作) 
tl = null;

System.gc();

2318 次点击
所在节点    程序员
9 条回复
szq8014
2020-05-12 18:08:13 +08:00
```tl = null; ```
这一行没有任何效果,ThreadLocal 这东西是跟线程绑定的,只要你不 remove 或者不把线程关掉,那你 set 的东西就一直在那里陪着线程。
想要泄漏就可以 set 一个 List 然后 list 一直往里加东西就可以了。
chendy
2020-05-12 18:08:39 +08:00
但是 ThreadLocal 本身还有个弱引用兜底,只要没有强应用就会被 gc 带走,所以可以说木有内存泄漏了
szq8014
2020-05-12 18:08:55 +08:00
具体见 java.lang.Thread#threadLocals
Uchiha0bito
2020-05-12 18:19:48 +08:00
每个线程都有一个 ThreadLocalMap,key 就是这个线程往哪些 ThreadLocal 存放了元素,value 就是对应存放的元素。key 泄漏可以由 jdk 解决,因为 key 引用是弱引用。但是 value 泄漏是没有解决的,需要用户每次使用完就移除,否则就一直在那儿
Uchiha0bito
2020-05-12 18:22:26 +08:00
所以 tl = null 这个不会导致泄漏,因为没有强引用存在的情况下 value 就被 gc 了。但是,如果是 t1.set(一个 User 对象),那这个 User 对象的强引用就一直被 ThreadLocalMap 存着了,不手动删掉就会泄漏
jinzhongyuan
2020-05-12 18:45:01 +08:00
@szq8014 这是内存溢出吧?
hangszhang
2020-05-12 22:55:29 +08:00
ThreadLocalMap 的 get 和 set 方法自己会清除数据,所以已经很难内存泄露了,但是最好还是养成用完 remove 习惯
szq8014
2020-05-13 08:58:20 +08:00
@jinzhongyuan 哈哈,是. 放了不删除就是泄露了,一直放了不管会溢出,2333
ica10888
2020-05-13 09:39:15 +08:00
Entry 是 ThreadLocal 的弱引用,非严格意义来说不会产生内存泄露。用 threadlocal 一般是在多个方法里面线程自己变量的存放,一般不讨论内存泄露的问题...

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/671002

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX