前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >源码解析:ThreadLocal(4)

源码解析:ThreadLocal(4)

作者头像
爪哇缪斯
发布2023-05-09 21:49:19
1310
发布2023-05-09 21:49:19
举报
文章被收录于专栏:爪哇缪斯爪哇缪斯

3.7> cleanSomeSlots(int i, int n)

  • 该方法返回的是boolean值

返回true:表示存在“陈旧”的Entry且已经被清除(但并不表示完全清除所有的“陈旧”Entry,只表示执行过这种操作)

  • 由于上面的expungeStaleEntry方法,已经在“施工”范围内,清除了所有“陈旧的”Entry,并且由于在这个范围内,是不包含空位置的,所以可以顺利的把这个范围内的所有“陈旧”Entry清除掉。
  • 那么cleanSomeSlots方法,则是以log2(n)的粒度,去清除一些“陈旧”Entry。
  • 方法上的注释翻译如下,可以理解为是对于提升插入速度和table数组内“陈旧”Entry整理耗时的一种平衡处理方案:

启发式扫描一些单元格以查找陈旧条目。当添加新元素或删除另一个陈旧元素时调用此方法。它执行对数扫描,作为不扫描(快速但保留垃圾)和扫描次数与元素数量成正比之间的平衡,这将找到所有垃圾但会导致某些插入花费 O(n) 时间。

  • 方法代码很少,源码和注释如下所示:

【解释】

removed如果为false,则可以理解为table数组里基本没有“陈旧”Entry。rehash是否执行的判断依据,其实用到了removed这个结果。

这就表示table数组中基本都是正常的Entry,并且触达到了阈值长度,那么就可以执行rehash操作了。从而避免了table数组由于存在大量“陈旧”Entry而导致rehash的情况发生。

  • 流程图如下所示:

3.8> rehash()

  • rehash其实包含两部分内容

1> 遍历table数组,清除表中的所有“陈旧”Entry。

2> 如果满足数组中存在的Entry数量 >= 3/4threshold,则进行resize()扩容操作。

  • 源码和注释如下所示:
  • 流程图如下所示:

3.9> expungeStaleEntries()

  • 该方法内部比较简单,就是遍历table数组里的Entry,调用expungeStaleEntry方法(expungeStaleEntry详情上面介绍了,这里就不再赘述了)
  • 源码和注释如下所示:

3.10> resize()

  • 扩容操作执行如下操作:
    • 按照原table数组长度,创造长度为2倍的新table数组。
    • 将旧table数组中的Entry插入到全新的table数组中,具体插入方式采用“开发地址法”。(前面也说过了,这里也不赘述了)
    • 根据新的table数组,更新全局变量:table、size、threshold。
  • 源码和注释如下所示:

四、ThreadLocal 内存溢出问题:

  • 通过上面的分析,我们知道expungeStaleEntry() 方法是帮助垃圾回收的,根据源码,我们可以发现 get 和set 方法都可能触发清理方法expungeStaleEntry(),所以正常情况下是不会有内存溢出的。
  • 但是如果我们没有调用get和set的时候就会可能面临着内存溢出。
  • 养成好习惯不再使用的时候调用remove(),加快垃圾回收,避免内存溢出。
  • 退一步说,就算我们没有调用get和set和remove方法,线程结束的时候,也就没有强引用再指向ThreadLocal中的ThreadLocalMap了,这样ThreadLocalMap和里面的元素也会被回收掉。
  • 但是有一种危险是,如果线程是线程池的,在线程执行完代码的时候并没有结束,只是归还给线程池,这个时候ThreadLocalMap和里面的元素是不会回收掉的。

(完)

本文参与?腾讯云自媒体分享计划,分享自微信公众号。
原始发表:2021-10-17,如有侵权请联系?cloudcommunity@tencent.com 删除

本文分享自 爪哇缪斯 微信公众号,前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与?腾讯云自媒体分享计划? ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
目录
  • 3.7> cleanSomeSlots(int i, int n)
  • 3.8> rehash()
  • 3.9> expungeStaleEntries()
  • 3.10> resize()
  • 四、ThreadLocal 内存溢出问题:
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
http://www.vxiaotou.com