HotSpot算法细节实现——安全点

OopMap

垃圾回收时,如何找到垃圾?

在可达性分析算法中从GC Roots集合找引用链分析对象是否可达。

固定可作为GC Roots的节点主要在全局性的引用(例如常量或类静态属性)与执行上下文(例如栈帧中的本地变量表),Java应用越做越庞大,光是方法区的大小就常有数百上千兆,里面的类、常量等更是恒河沙数,若要逐个检查以这里为起源的引用肯定得消耗不少时间。

迄今为止,所有收集器在根节点枚举这一步骤时都是必须暂停用户线程,因此根节点枚举也会面临相似的"Stop The World"的困扰。

根节点枚举必须在一个能保障一致性的快照中才得以进行 ------"一致性":整个枚举期间执行子系统看起来就像被冻结在某个时间点上,不会出现分析过程中,根节点集合的对象引用关系还在不断变化的情况,是导致垃圾收集过程必须停顿所有用户线程的其中一个重要原因

实际上虚拟机应当是有办法直接得到哪些地方存放着对象引用的,HotSpot的解决方案中,是使用一组称为OopMap的数据结构来达到这个目的。(一旦类加载动作完成的时候,HotSpot就会把对象内什么偏移量上是什么类型的数据计算出来,在即时编译过程中,也会在特定的位置记录下栈里和寄存器里哪些位置是引用。)

安全点

在OopMap的协助下,HotSpot可以快速准确地完成GC Roots枚举,但没有为每条指令都生成OopMap。

"特定的位置"记录了这些信息,这些位置被称为安全点(Safepoint)

安全点是以 "是否具有让程序长时间执行的特征"为原则进行选定 的,所以方法调用、循环跳转、异常跳转这些位置都可能会设置有安全点

有了安全点的设定,也就决定了用户程序执行时并非在代码指令流的任意位置都能够停顿下来开始垃圾收集,而是强制要求必须执行到达安全点后才能够暂停。只有在安全点位置才能进行垃圾收集

垃圾收集刚开始的时候需要先获取所有根节点(根节点枚举),而根节点的获取依赖所有线程抵达安全点。

可数循环&不可数循环

HotSpot虚拟机为了避免安全点过多带来过重的负担,对循环还有一项优化措施 ,认为循环次数较少的话,执行时间应该也不会太长,所以使用int类型或范围更小的数据类型作为索引值的循环默认是不会被放置安全点。这种循环被称为可数循环(CountedLoop)

使用long或者范围更大的数据类型作为索引值的循环就被称为不可数循环(Uncounted Loop),将会被放置安全点

可数循环不会被放置到安全点,不可数循环会被放置到安全点

通常情况下这个优化措施是可行的,但循环执行的时间不单单是由其次数决定,如果循环体单次执行就特别慢,那即使是可数循环也可能会耗费很多的时间。

如果由可数循环耗时时间较长,安全点导致长时间停顿,可以将循环索引的数据类型从int改为long即可

现象:

当垃圾收集发生时,如果有线程刚好执行到可数循环(较耗时)时,则必须等待循环全部跑完才能进入安全点,此时其他线程也必须一起等着,所以从现象上看就是长时间的停顿。

出现可数循环比较耗时,可以将循环索引的数据类型从int改为long。 将可数循环变为不可数循环,放置到安全点位置即可。

相关推荐
yt9483240 分钟前
JVM如何优化
jvm
全干engineer44 分钟前
web3-基于贝尔曼福特算法(Bellman-Ford )与 SMT 的 Web3 DeFi 套利策略研究
算法·金融·web3·去中心化·区块链·智能合约
像素工坊可视化1 小时前
监控升级:可视化如何让每一个细节 “说话”
运维·人工智能·安全
Splendid1 小时前
Geneformer:基于Transformer的基因表达预测深度学习模型
javascript·算法
程序员阿超的博客1 小时前
【安全篇】金刚不坏之身:整合 Spring Security + JWT 实现无状态认证与授权
java·spring boot·安全·spring
好想打kuo碎1 小时前
轻量安全的密码管理工具Vaultwarden
linux·安全·ubuntu
愿所愿皆可成1 小时前
机器学习之聚类Kmeans算法
算法·机器学习·kmeans·聚类
幻奏岚音1 小时前
统计学(第8版)——假设检验学习笔记(考试用)
笔记·学习·算法
hie988942 小时前
基于matlab策略迭代和值迭代法的动态规划
算法·动态规划
Coovally AI模型快速验证2 小时前
SFTrack:面向警务无人机的自适应多目标跟踪算法——突破小尺度高速运动目标的追踪瓶颈
人工智能·神经网络·算法·yolo·计算机视觉·目标跟踪·无人机