【JVM】并发的可达性分析

1 篇文章 0 订阅

并发的可达性分析

在进行对象的可达性分析时,如果是全程STW是没问题的,但是在垃圾回收时暂停全部用户线程的活动会让使用者的体验非常差。

但是如果在进行可达性分析时,用户线程和垃圾收集线程并发运行,可能用户线程会同时对引用关系进行修改。

“并发”的可达性分析,这里的并发指的是用户线程(可以是多个用户线程)和垃圾收集线程一起运行。

我们引入三种颜色对遍历对象图进行分析:

  • 白色:表示对象仍未访问到。如果到可达性分析结束后,对象仍为白色就说明对象不可达。
  • 灰色:表示对象已经被访问到,但是对象的所有引用还没有都被扫描完。
  • 黑色:表示对象已经被访问到,并且对象的所有引用都被扫描完了。如果有其他对象指向黑色对象,则无需重新扫描,黑色对象不会直接指向白色对象(因为黑色对象的所有引用都扫描完了)

如果在进行可达性分析时,用户进程也在并发执行,那么就可能会出现两种问题:

  • 本来”死亡“的对象被标记为存活
  • 本来存活的对象被标记为”死亡“

第一种情况其实问题不大,因为垃圾回收是要保证所有回收的对象都是”死亡“的对象,即使有一些”死亡“的对象在这一次垃圾收集中没有被回收,也是可以的。

但是第二种情况问题就比较严重了,如果本来存活的对象给回收掉,那么用户程序就会发生错误,所以在进行并发可达性分析时要避免第二种情况,这种情况称为“对象消失”

那么根据刚才三种颜色的定义,如果发生“对象消失”需要两个条件:

  • 插入了一条或多条从黑色对象到白色对象的引用
  • 删除了全部从灰色对象到该白色对象的直接或间接引用

这两个条件就可以理解为:把后续扫描中可以扫描到该白色对象的路径都删除掉了,并且引入了之前已经扫描完的对象到该白色对象的路径。那么这样的话,虽然这个对象最后应该是存活的,但是也没有办法扫描到该对象,则会把它当作不可达的对象进行回收。
《深入理解Java虚拟机》中的举例

如果要解决“对象消失”的问题,只需要破坏其中一条条件即可。

第一种方法是增量更新,是破坏第一个条件“插入了一条或多条从黑色对象到白色对象的引用”,当有黑色对象指向白色对象时,就把该黑色对象变成灰色对象,回头再重新扫描一次,这样就可以保证指向的白色对象一定会扫描到。

第二种方法是原始快照,是破坏第二个条件“删除了全部从灰色对象到该白色对象的直接或间接引用”,如果要删除灰色对象到白色对象的直接或间接引用时,把这个引用记录下来,回头再以这个记录的引用关系中的灰色对象为根,重新扫描一次。可以理解为虽然这个引用记录删除了,但是还是按原先的引用关系进行扫描。

之前不太理解原始快照这种方法,现在记录一下我自己的理解。

原始快照这种方法就是即使用户删除了一条灰色到白色的直接或间接引用,最后仍然是按照原先的记录来进行扫描,也就是说仍然当这条引用存在。

虽然这样做可能会出现“浮动垃圾”,即本来“死亡”的对象被标记为存活,但是无伤大碍,只要保证存活的对象没有被回收即可。

以上对对象引用关系的插入或删除,虚拟机对该操作的记录都是通过写屏障实现的。

CMS收集器使用的是增量更新,G1和Shenandoah使用的是原始快照。

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值