美文网首页
“ThreadLocal内部的ThreadLocalMap键为弱

“ThreadLocal内部的ThreadLocalMap键为弱

作者: __无语__ | 来源:发表于2023-02-11 17:54 被阅读0次

    之前的一个评论,博主把文章删除了。

    ThreadLocal内部的ThreadLocalMap键为弱引用,会有内存泄漏的风险,真的是这样吗?

    我认为不太合理。原因是:

    1. ThreadLocalMap中的Entry弱引用(key)到的是 threadLocal 对象,
      此处的弱引用意图是,当外界不再持有对 threadLocal 对象的强引用的时候,
      threadLocal 对象可以被GC。此处Entry对 threadLocal 的弱引用不会引起内存泄露。

    2. Entry除了持有对threadLocal的弱引用之外还持有对value的强引用。
      先说为什么调用了threadLocal.remove() 就解决了内存泄漏的风险。
      threadLocal.remove() 这个方法最终会有机会执行到:
      entry.value = null;
      entry = null;
      这样就解除了entry对value的强引用关系,当外部也没有对value的强引用的时候,
      value就可以被GC。

    如果不调用threadLocal.remove() 这个方法,其实也是要分情况来考虑的。
    我们知道 entry 是被 threadLocalMap 引用的;而 threadLocalMap 是被 thread 引用的。
    如果一个thread执行完毕,进入 TERMINATED 状态时,作为一种GC Root,
    terminated 状态的 thread本身就是可以被GC的。
    那么thread所引用的 threadLocalMap 也就是可以被GC的。

    那么什么情况下 threadLocalMap 不能被回收呢?
    那就是thread并不会进入 terminated 状态的时候。
    什么时候不进入 terminated 呢?就是当 thread 配合线程池使用的情况下,thread在运行完毕之后
    会被再次放回线程池。
    那么如果这个线程永远不被用到,此处的threadLocalMap 包括entry 和 entry引用的value 就不能被回收了。
    那么如果这个线程被再次启用,那么threadLocalMap也就不会再重新初始化了。
    此处应该考虑另外一个问题,那就是如果再次调用 threadLocal.get() 方法,得到的是上一次set的内容,
    也就是脏读了。

    相关文章

      网友评论

          本文标题:“ThreadLocal内部的ThreadLocalMap键为弱

          本文链接:https://www.haomeiwen.com/subject/lkcrkdtx.html