菜鸡每日一面系列打卡28天
每天一道面试题目
助力小伙伴轻松拿offer
坚持就是胜利,我们一起努力!
题目描述
Java的G1收集器你了解多少?
题目分析
在上一篇文章中,我们讲述了CMS收集器的基础知识,收集算法及其优缺点,而本文要讲到的是另一个里程碑式的垃圾收集器G1(Garbage First)。
上一篇文章提到的CMS收集器是HotSpot虚拟机追求低停顿的第一次成功尝试,而G1收集器设计之初的目标就是最终替代CMS!事实也确实如此,在JDK9发布之后,CMS已经被声明为Deprecate。
那么,到底为什么G1被称为里程碑式的垃圾收集器,又为何能有望取代CMS收集器呢?接下来,随菜鸡一起去看看吧!
题目解答
01
G1收集器简介
G1收集器是垃圾收集器技术发展历史上的里程碑式的成功,它开创了收集器面向局部收集的设计思路和基于Region的内存布局形式,是一款主要面向服务端应用的垃圾收集器。这段话点出了菜鸡认为G1与其他收集器最大的不同,它是整个设计理念上的转变。
上一篇文章中我们提到的CMS收集器,是一款优秀的并发低停顿的收集器。而G1的设计者认为这种低停顿是不够的,而是需要更进一步的可预测的停顿。所谓的可预测的停顿,就是建立一个“停顿时间模型”,能够支持指定在一个长度为M毫秒的时间片段内,消耗在垃圾收集上的时间大概率不超过N毫秒。这给出了一个比较严格的数学约束。实现这样的模型如果还是仅仅依靠之前的设计理念是难以达到的,为此,G1开创性地采用了基于Region的堆内存布局。
那么问题来了,Region是一个怎样的概念?Region其实就是一个个Java堆的小的分区。在G1的眼中,新生代和老年代是一个逻辑性的定义,而不再是固定的内存区域。换句话说,每个Region可以根据具体情况承担新生代或老年代的角色,G1会对不同角色施加不同的策略。
02
G1收集器的特点
G1收集器的运作大致分为以下几个步骤:
初始标记(stop the world):标记GC Roots直接关联的对象,并修改TAMS指针的值,让下一阶段用户线程并发运行时,能正确地在可用的Region中分配新对象。
并发标记(concurrent):从GC Roots开始遍历对象图。
最终标记(stop the world):处理并发标记过程中有引用变动的对象。
筛选回收(stop the world):负责更新Region的统计数据,对各个Region的回收进行优先级排序。
G1收集器的特点:
可以指定最大停顿时间。
分Region的内存布局。
按收益动态确定回收集。
整体基于“标记-整理”算法,局部(Region之间)基于“标记-复制”算法。
03
总结
G1如此优秀,然而并不能说全方位碾压CMS。事实上,G1只是表现更均衡,因此才“更完美”。垃圾收集器性能的好坏主要有三个评判标准:内存占用,吞吐量,延迟。想要同时保证三者的完美几乎是不可能的。其实在工程上,很多时候我们需要基于实际情况寻找一个平衡点。这不是个例,而是普遍存在的,比如服务的CAP理论,也是这样的一个经典例子。
基于一些客观事实和某些认识,我们可以尝试进行如下总结,囿于菜鸡的水平,仅供大家参考。很多事物的发展变化,都是有固定到灵活(比如由物理概念转向逻辑概念),由强限制到弱限制(比如理论的扩展),由粗糙到细致(比如自定义的出现,以及优先级的概念)。这些基于某些原则下的变化会由整体扩展到局部再回到重塑整体本身。这是抽象的过程,期间会伴随着模型的建立和更高维度的抽象。
以上便是菜鸡对G1收集器的一些总结,供大家参考。
参考资料
《深入理解Java虚拟机》第3版 周志明
相关链接
学习 | 工作 | 分享
????长按关注“有理想的菜鸡”
只有你想不到,没有你学不到