Java垃圾收集器-G1

垃圾收集器发展历史

No1. Serial收集器 & ParNew收集器
Serial收集器是比较早推出的,大概从JDK1.3开始吧,顾名思义,单线程工作的,且工作时要停止用户所有工作线程,一个词概括:简单粗暴,因此实现起来也比较简单,但"暂停一切"实在太恶心了,人们形象的形容为"Stop The World"

ParNew是其多线程版本,本质并没有太多区别。这个时期的收集器处于起步不完善阶段。

No2. CMS收集器
这是真正具有划时代意义的收集器,大概从JDK5开始,直到现在应该还有不少web服务在使用,它尝试改变"Stop The World",追求低停顿,基于标记-清除算法,将整个过程划分阶段,有些阶段可以与用户线程并发工作,减少停顿时间,但基于标记-清除的策略难免有内存碎片等问题,但相对来说已经标志着垃圾收集器走向成熟。

No3. Garbage First(G1)

也就是本文要介绍的重点,已在JDK9成为默认收集器,意在取代CMS,详细后文再谈。

No4. ZGC

代表着目前可见的未来,追求极致的低延迟、高吞吐体验,JDK11已推出,还在不断完善优化中。

Garbage First(G1)收集器

从JDK6实验版本到JDK8全功能商用版本,目前已足够成熟。

追求低延迟与高吞吐之间的平衡。

它开创了基于Region的内存布局、垃圾回收方式。所谓的Region就是一个个"棋盘格子",不再区分新生代老年代,一切都划分在一个个区块内,可以支持"格子"级别的垃圾收集,而以往的收集器(包括CMS)都只能对新生代或老年代完全收集,这是一个开创性的算法思想转变。
在这里插入图片描述
其中,E: Eden Space,S: Survivor Space,O: Old Generation

格子分好后,对每个格子建立回收价值模型(使用回收释放空间、停顿时间等来衡量回收价值),以最大价值原则,根据设置的允许停顿时间(-XX:MaxGCPauseMillis),衡量需要回收哪些格子,回收多少格子。

回收过程分四步

初始标记:标记GC Roots直接关联对象,维护可用内存指针位置,保证后面并发垃圾标记时可以同时正确分配新内存给用户。

并发标记:扫描GC Roots,找出可回收对象,打标记。

最终标记:简单说就是对并发标记过程查缺补漏。

筛选回收:根据前面说的价值优先原则回收需要回收的格子。

其中,并发标记可以与用户线程一起执行,其他都要暂停用户线程,并发标记时间是最长的,这步能并发执行收益真的很大。

关键算法

1.标记-整理

这意味着回收格子时,把存活对象复制到另一个格子,然后把格子整个回收,最后移动整理格子防止产生内存碎片

跟玩积木似的。。
在这里插入图片描述
2.SATB快照

前面提到,并发标记能做到与用户线程并发,真的没有问题么?当然有,一个突出问题就是,程序运行在不断改变对象引用结构,一边回收线程又在遍历标记对象,冲突了怎么办,不小心把回该留下的回收了可就要命了。

因此,CMS采用增量更新算法,G1采用SATB快照算法解决该问题。

快照算法简单来说就是无论引用关系删除与否,都会按开始扫描一刻的快照图来搜索,还是很形象的。

3.卡表
为减少对GC Roots扫描范围,维护一个存在跨代引用的表格,每次只对这些进行GC Roots扫描,G1的卡表相对来说更加复杂,因为它是可以按格子细粒度回收,就需要额外维护格子间引用的信息,使得卡表更加复杂,这也是它相比CMS等回收器的劣势之一。







在这里插入图片描述
扫码关注同名微信公众号“大眼歪哥”,快乐学习,共同进步!

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值