Shenandoah收集器详解

前言

Shenandoah收集器是不被Oracle公司承认的,所以只有在OpenJdk才可以使用,在OracleJdk中是没法使用的。Shenandoah收集器相比交于血统纯正的ZGC收集器,更像是G1的继承者。他们很多方面都比较相似,而且他们甚至还共享了一段代码。

Shenandoah收集器简介

Shenandoah收集器和G1类似,也是基于region的堆内存布局进行垃圾回收,同样有这放大对象的区域,默认回收策略,也是优先回收有价值的region。但是他在内存回收上面和G1有很多不同。
1.支持并发的整理回收算法。
2.默认不使用分代集
3.不使用记忆集,改为连接矩阵

Shenandoah收集器工作过程

Shenandoah收集器的工作过程大致分为九个过程
1.初始标记
与G1一样,都是简单标记和GCroot直接关联的对象
2.并发标记
与G1一样,遍历对象图,标记全部可达对象,和用户线程一起并发的
3.最终标记
与G1一样,处理剩余的stable
4.并发清理
清理一个存活对象都没有的region
5.并发回收
G1之所以做不到并发回收,是因为如果在移动对象的同时可以修改对象的话,移动完之后,对象还是指向的就地址,很难一瞬间改过来。Shenandoah收集器怎么解决这个问题的呢,它是通过读屏障和转发指针来解决的。(转发指针讲起来很麻烦,稍后再讲)
6初始引用更新
建立线程集合点,确认所有线程都已完成分配给对象的移动任务
7.并发引用更新
回收阶段结束后,把对象的指针从旧对象改为新对象。
8.最终引用更新
修正GcRoot的引用
9.并发清理
回收region空间

Brooks 转发指针

Brooks转发指针和java的句柄定位有点类似,不过差别是句柄通常会统一存储在句柄池中,而转发指针是分散存放在每一个对象头前面。这样的设计,决定的了必然会出现多线程竞争。
1.收集器线程复制了新的对象副本
2.用户线程更新对象的某个字段
3.收集线程更新转发指针的引用值为新副本地址
如果不做保护措施的话,让事件二发生在一和三之间,将导致用户线程对对象的变更,在一三之间,将导致的结果就是用户线程对对象的变更发生在旧对象上。所以必须对用户的访问操作采取同步措施,让收集线程和用户线程,只能有一个成功,另一个必须等待。实际上是通过cas操作来保证并发的。
对象访问是很频繁的,如果都加上读写屏障,消耗很大,所以Shenandoah收集器将读写的屏障,改为引用读写的屏障,也就是只对对对象引用类型数据修改加屏障。而不是整体加,就避免不是访问指针,而是访问其他数据也加屏障。

总结

Shenandoah收集器整体来说还是很不错的,但是因为不被官方支持,兼容性方面还是有很大的问题的。他的停顿时间虽说比其他几款收集器有了质的飞跃,但是还是没有实现控制在10毫秒之内,吞吐量方面也有了很大的下降,总运行时间也是十分的长的,但是依然是一款十分不错的收集器。

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

mark---小鑫

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值