当前位置: 首页 > news >正文

HotSpot的算法细节

可达性分析算法

以一系列“GC Roots”根对象作为起始节点集,从这些节点开始,根据引用关系向下搜索,搜索过程所走过的路径称为“引用链”(Reference Chain),如果某个对象到GC Roots间没有任何引用链相连, 或者用图论的话来说就是从GC Roots到这个对象不可达时,则证明此对象是不可能再被使用的。

从GC Roots开始向下进行引用搜索,如果某对象和任何GC Root没有关联,则认为该对象不再被使用。

GC Roots

  • 虚拟机栈中引用的对象,对应虚拟机方法栈中当前执行的方法所使用的参数,局部变量,临时变量等。
  • 方法区中:类的静态变量,常量
  • 本地方法栈中引用的对象

记忆集与卡表

记忆集是一种用于记录从非收集区域指向收集区域的指针集合的抽象数据结构。

卡表:是记忆集的一种实现形式,采用的是“卡精度”的方式实现记忆集。卡精度指精确到一块内存区域(该内存区域又称为“卡页”),这个区域内有跨代指针的话,就将其标识出来(实际是使用的0/1标识);

在进行GCROOTS扫描时,同时再去筛选卡表中变脏的元素(扫描指定的内存区域块),可以快速定位到关联区域,将跨区引用的对象一起加入GCROOTS扫描。

写屏障

写屏障主要解决的是卡表元素的维护更新,即处理卡表变脏的问题。

何时变脏:其他分代区域有对象引用了该区域对象时,其对应的卡表元素则变脏。

写屏障的处理类似于一个AOP切面,即在本区对象被引用时,添加了Around环绕通知,可在引用赋值前后添加写前屏障和写后屏障。通常虚拟机在写后屏障中增加维护卡表的操作。

卡表在高并发场景下还存在伪共享的问题,由于64个卡表共享一个缓存行,当多个线程更新同一缓存行数据时,会出现并发更新影响性能的情况。

同时虚拟机提供-XX:+UseCondCardMark参数配置,开启该参数则会预先检查该卡表是否已变脏,再行更新的策略。对未变脏的进行更新,已经变脏的卡表不再更新。开启该参数增加异常额外判断的开销,但可以避免伪共享的问题

SATB(snapshot at the beginning)原始快照

沿着GCRoots进行并发扫描时,通常用户线程也在并发执行。这时会面临着已经被垃圾收集器扫描的对象图被用户线程更改的情况。

情况一:某些对象被用户线程断开了引用,其实该对象已经成为垃圾,现在仍被垃圾收集器标识为存活

情况二:某些被垃圾收集器标识为垃圾的对象被用户线程重新引用,导致存活对象被垃圾收集器回收了

综合以上两种情况可知,情况一其实可以容忍,只是程序产生了一些浮动垃圾,待下一次垃圾收集时可以一并回收。情况二把原本存活的对象标记为了死亡,则会造成程序的致命错误。

关于情况二即并发扫描时的对象消失问题,不同的垃圾收集器的解决办法不同。CMS中使用增量更新的方式,G1和shenandoah采用原始快照的方式。

CMS使用增量更新的方式:

当有黑色对象插入指向白色对象的引用时,就将这个引用关系记录下来。在并发扫描结束后(最终标记),以这些黑色对象为根再次进行扫描一次。

垃圾收集器扫描完成的对象引用了一个未被扫描过(新创建或已断开引用)的对象,会将该引用关系记录下来,在最终标记阶段再以该新创建的对象为根,再次进行扫描一次。

G1和shenandoah的原始快照方式:

当灰色对象要删除一个指向白色对象的引用时,就将该要删除引用关系记录下来。在并发扫描结束再以这些灰色对象为根进行扫描一次。这种做法最终导致无论关系删除与否,都会按照垃圾收集器开始扫描的那一刻的对象图来进行对象搜索。

TAMS(Top at mark start)标记顶部

G1收集器中的概念,G1为每个region设计两个TAMS的指针,用于在并发回收阶段新的对象的分配。在回收阶段新对象分配的内存地址将落在region的两个TAMS指针之间。G1默认在两个指针之间的对象是存活的,不对其进行垃圾回收。

相关文章:

  • 集群系统的五大核心挑战与困境解析
  • 4月28号
  • 漏洞复现清单整理-预备梳理,等待补充
  • 多维驱动:负载均衡何以成为现代系统架构的基石
  • 网络爬取需谨慎:警惕迷宫陷阱
  • Ansible安装配置
  • 代发考试战报:4月份 思科认证,华为认证,考试战报分享
  • Twitter 工作原理|架构解析|社交APP逻辑
  • 洛谷题解 | CF1979C Earning on Bets
  • <Revit二次开发> 通过一组模型线构成墙面,并生成墙。Create(Document, IList.Curve., Boolean)
  • 以梦为舟,驶向中医传承新蓝海
  • 宾馆一次性拖鞋很重要,扬州卓韵酒店用品详细介绍其材质与卫生标准
  • Windows 系统下使用 Docker 搭建Redis 集群(6 节点,带密码)
  • (计数)洛谷 P8386 PA2021 Od deski do deski/P10375 AHOI2024 计数 题解
  • Java项目中使用minio存储服务
  • softlockup_panic=1配置方法及区别
  • 基于论文的大模型应用:基于SmartETL的arXiv论文数据接入与预处理(四)
  • 常见的 CSS 知识点整理
  • 实验七:基于89C51和DS18B20的温度采集与显示
  • 源码角度分析 sync.map
  • 五月院线片单:就看五一档表现了
  • 习近平访问金砖国家新开发银行
  • 王毅会见泰国外长玛里:坚决有力打击电诈等跨境犯罪
  • 上海“生育友好岗”已让4000余人受益,今年将推产假社保补贴政策
  • 朝鲜证实出兵俄罗斯协助收复库尔斯克
  • 哈马斯官员:只要以军持续占领,哈马斯就不会放下武器