想请问下关于 ThreadLocal 的使用

2022-09-17 17:44:14 +08:00
 e1o
我们一般在使用 ThreadLocal 的使用,都会将它定义为静态变量或者成员变量,这样每次 set 和 get 完之后就直接不用管就行,但是为啥网上的文章都说要调一下 remove 要不然内存溢出,我个人的理解是,随着线程的终结,线程内部的 ThreadLocalMap 中,key 是弱引用 GC 会直接消失,value 的话在 GC 的时候因为没有 GCROOT 关联,所以也会被清除掉才对把,是我理解的有偏差吗?
1860 次点击
所在节点    Java
12 条回复
duanqw
2022-09-17 17:57:13 +08:00
线程是重复利用的,所以要删除
urnoob
2022-09-17 17:57:15 +08:00
关键是
1 平时开发中跑你代码的线程都是只有 jvm 退出它们才终结啊 它们可能是 tomcat jetty 或者线程池的线程。
2 value 不能被 gc 因为 threadlocalmap 还引用了它。
sprite82
2022-09-17 18:00:22 +08:00
tomcat 初始化 200 个线程,某个线程处理完这个有 threadlocal 的请求,下一次可能处理其他请求了
e1o
2022-09-17 18:14:28 +08:00
@duanqw
@sprite82 那就是说虽然我没有定义线程池,但是像用的 springboot 这种框架,它其实隐式地使用了 Tomcat 自带的线程池是吗?
e1o
2022-09-17 18:15:51 +08:00
@urnoob 但是我的 threadlocalmap 没有 gcroot 指向它,根据可达性算法,threadlocalmap 和它下面的 value 应该都被干掉才对呀
cowcomic
2022-09-17 19:01:46 +08:00
Hurriance
2022-09-17 19:09:16 +08:00
你说的没问题,如果线程在处理完请求后它是会被销毁的话,你说的 ThreadLocal 和 Thread 这两个实例对象都是会被回收的,因为他们并没有被虚拟机栈引用到了,即你说的没有跟 GCROOT 关联,但在服务端开发下的绝大多数情况,都是这个线程完成处理了这次请求,有关 ThreadLocal 的栈帧都出栈了,此时 ThreadLocal 实例对象就是能被回收的了,但是线程还是会被重复利用处理其他请求,但是线程中的 ThreadLocalMap 的 key 又是指向 ThreadLoca 实例对象的弱引用,相当于指向为空,导致后期不能被回收了,即内存泄露
zed1018
2022-09-17 19:12:24 +08:00
> 那就是说虽然我没有定义线程池,但是像用的 springboot 这种框架,它其实隐式地使用了 Tomcat 自带的线程池是吗?

不然你认为 spring mvc 是怎么同时处理请求的呢。
e1o
2022-09-17 21:33:37 +08:00
@Hurriance 好吧
e1o
2022-09-17 21:33:49 +08:00
@zed1018 了解了
leonme
2022-09-18 00:09:05 +08:00
@Hurriance 解释的很明白
goalidea
2022-09-19 10:28:45 +08:00
线程池

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

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

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

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

© 2021 V2EX