前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >并发的可达性分析

并发的可达性分析

作者头像
小土豆Yuki
发布2021-01-29 12:21:05
6520
发布2021-01-29 12:21:05
举报
文章被收录于专栏:洁癖是一只狗洁癖是一只狗

我们知道JVM是利用可达性分析算法来判断对象是否存活,可达性分析算法理论上要求全过程基于一个能保障一致性的快照中进行分析,这意味着必须冻结用户线程的运行。

又由于GC Roots相比这个堆中的全部对象毕竟还是少数,且在各种优化中,他带来的停顿是非常短暂的,但是从GC Roots再继续往下扫描遍历对象图,这一步骤的停顿时间和堆的容量是成正比的,因此他会随着堆的变大而产生的停顿时间更长,会影响几乎所有的垃圾收集器,因此我们要是能够消减这部分的停顿,那收益就是系统级别的。

此时如果我们想要解决或者降低用户线程的停顿,就必须知道为什么必须要保障一致性快照上才能进行对象图的遍历,因此我们引入三色标记来作为辅助来理解

  • 黑色,表示对象已经被访问过,且这个对象的所有引用都已经被扫描过
  • 白色,表示对象还没有被访问过
  • 灰色,表示对象已经被垃圾收集器扫描过,但这个对象至少存在一个引用还没有扫描过

我们看到上面图片,当我们进行可达性分析的时候,当扫描到2节点的时候,这个时候,由于用户线程的的干扰,就会变成下面图片

这里2正准备到扫描4节点的时候,用户线程对应用进行了修改,把3到4的引用删除了,添加了2到4的引用,又由于2是黑色节点已经被扫描过了,就不会重新扫描他的子节点,此时4节点还是白的,因此JVM此时就会认为4已经不可达了,就会回收这个本应该存活的对象,就会导致2对象引用4的时候报错,这个中操作非常致命的.

为什么会出现这样的问题呢,原因如下

  1. 赋值器插入了一条或多条从黑色到白色对象的新引用
  2. 赋值器删除了全部从灰色对象到该白色对象的直接或间接引用

上面两者共存才会导致致命的问题,单单一个条件是没有影响的,如下图,删除一个旧的引用,就不会影响

或者添加一个引用也不会影响

因此只有两个条件同时存在,才会出现问题,所以我们只要破坏掉其中一条就可以了,因此出现了两种方案.

  1. 增量更新,破坏第一条,当黑色对象插入新的指向白色对象的引用关系时候,就将这个新插入的引用记录下来,等并发扫描完之后,再将这些记录过的引用关系中的黑色为根节点重新扫描一次。
  2. 原始快照,破坏第二条,当灰色对象要删除指向白色对象的引用关系时候,就将这个要删除的引用关系记录下来,等并发扫描完之后,在将这些记录过的引用关系中的灰色对象为根节点,重新扫描一次.

我们知道cms垃圾收集器使用的就是增量更新来做并发标记的,而G1则是利用原始快照来实现的,下次我们在再分析这两个垃圾收集器,敬请期待。

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

本文分享自 洁癖是一只狗 微信公众号,前往查看

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

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

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档