请稍等 ...
×

采纳答案成功!

向帮助你的同学说点啥吧!感谢那些助人为乐的人

关于弱引用的回收时机的疑惑

ThreadLocalMap.Entry中,key为ThreadLocal,这个ThreadLocal是个弱引用,
感觉这个知识是跟虚拟机有交集的,在此请教一下

  1. JVM在什么时机下判断 ThreadLocal 这个引用不再使用了,以下的情况会GC吗?
    1.1 情况一:线程池阻塞等待任务
    1.2 情况二:service调用链有同步操作,线程较长时间阻塞

  2. 线程池核心线程正在阻塞等待队列,此时Thread中的ThreadLocalMap对象会不会GC?
    2.1 如果会GC
    如果GC触发,线程池就失去了 set(object) 的object
    我可不可以认为
    线程池的场景,就算ThreadLocalMapGC,
    重写initialValue()方法,get的时候可以重设一个object进去,
    这个object应该是无状态的,如工具类SimpleDateFormat依旧保证业务逻辑健壮

正在回答

1回答

无论是线程怎么阻塞,都不代表这个线程会被回收,ThreadLocal也不会被回收。

判断回收的条件,主流是引用可达法法,程序运行从开始,每次引用对象,都将对引用的对象进行连接起来,到最后形成一张网,没有在这张网上的对象则被认为是垃圾对象。 

线程阻塞是不影响这张网的。


ThreadLocalMap是Thread的成员变量,是强引用,所以也是不会被回收的。

1 回复 有任何疑惑可以回复我~
  • 提问者 ych_1997 #1
    好的,我现在从另外个角度思考。课程里第二种用法中,public static ThreadLocal ,该对象 t1 是单例的,该对象指向地址0x11。
    A线程的 ThreadLocalMap  中有 key 为 t2 的 Entry。
    B线程的 ThreadLocalMap 中有 key 为 t3 的 Entry。
    t1, t2, t3同时指向地址0x11(引用是传递地址)。
    至于t2, t3是弱引用,这样设计的目的是什么?我猜测是只要 t1 不再指向0x11, 地址0x11的内存就可以被回收。对应的代码是t1 = null。我觉得这个是弱引用的实质作用。简单来说,当ThreadLocal的地址0x11只被弱引用指向,同样会被回收,GC回收的不是对象,而是对象在内存中的空间。阿里规约中强制remove,因为remove最终调用的是expungeStaleEntry(i),才是真正清掉Entry的所有内存占用。 我的思考关键是从【GC回收的内存,而不是对象】,结论是【虚引用关心的是指向的地址,维护的是指向地址的回收,与课程中value的回收无关,虚引用和value的回收都发生在remove方法里】。我好像逻辑能够自洽了,还需点拨!
    回复 有任何疑惑可以回复我~ 2020-01-11 20:41:01
  • 悟空 回复 提问者 ych_1997 #2
    是的呀,设计弱引用是回收ThreadLocal的,和value的回收无关
    回复 有任何疑惑可以回复我~ 2020-01-12 23:53:08
  • 提问者 ych_1997 #3
    非常感谢!
    回复 有任何疑惑可以回复我~ 2020-01-14 20:47:46
问题已解决,确定采纳
还有疑问,暂不采纳
意见反馈 帮助中心 APP下载
官方微信