HotSpot垃圾算法实现之枚举根节点和安全点安全区域

在根可达性分析算法中,从GC Roots集合中找引用链是虚拟机高效实现的第一个例子。

问题一:为什么要枚举根节点?怎么高效实现?

在这里插入图片描述
虽然GC Roots的节点主要在全局性的引用(例如常量或者类静态变量)与执行上下文(例如栈帧中的局部变量表),但是查找起来并发容易的事。

问题一解决之道:使用根可达分析算法判断垃圾,所以需要枚举根节点。通过在安全点生成并维护OopMap来高效计算GC Roots集合。

为了解决某个时刻GC Roots集合的定位问题,在HotSpot中,有个数据结构(映射表)称为OopMap。一旦类加载动作完成的时候,HotSpot就会把对象内什么偏移量上是什么类型的数据计算出来,记录到OopMap。在即时编译过程中,也会在特定的位置生成 OopMap,记录下栈上和寄存器里哪些位置是引用。这样在垃圾收集器在枚举根节点时,就可以通过扫描OopMap中的对象快速得到当时的GC Roots集合。
(每个安全点都会生成对应的OopMap)

问题二:为什么需要安全点?安全点在哪些位置?

进行垃圾回收的过程中,会涉及对象的移动。为了保证对象引用更新的正确性,必须暂停所有的用户线程(会发生STW)。线程并不是在任意位置都能中断挂起的,只有在特定的位置才行。
这些特定的位置:

  • 方法调用
  • 循环跳转(非 counted 循环,固定循环次数)
  • 异常跳转
    称之为安全点(每个安全点都会生成对应的OopMap),垃圾收集时,需要用户线程到达安全点停下来后才开始执行。

在HotSpot中,采用主动式中断的思想让做垃圾收集时让所有用户现在都跑到最近安全点停顿下来。
是在安全点和分配对象时设置一个中断标志,各线程执行时会不停轮询这个标志,一旦发现为真时就在最近安全点主动挂起。

问题三:为什么需要安全区域?

安全点的设计几乎完美解决如何停顿用户线程,让虚拟机进入垃圾回收状态。可如果用户线程处于Sleep或者Blocked状态时,线程是无法响应中断请求的,虚拟机也不可能等待线程被激活后走到安全点挂起自己,这个时候就需要安全区域来解决了。

安全区域是指能够确定在某一段代码之中,引用关系不会发生变化,因此这个区域内任意地方开始垃圾回收都是安全的。(安全区域是扩展了的安全点)

参考资料

  • 周志明 * 《深入理解Java虚拟机》
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值