JVM学习六.G1垃圾收集处理器详解

面向的场景:
面向服务端应用的一款垃圾收集器。

G1垃圾收集器的特点:

1.并行&并发
G1能充分利用多CPU,多核环境下的硬件优势,使用多个CPU来缩短STW停顿的时间。
我们再上一篇CMS垃圾收集器中说到,CMS垃圾收集器再初始标记的过程中STW.
但是G1不同,它依然可以通过并发的方式让Java程序执行。
2.分代收集
与其它收集器一样,分代概念仍然再G1中依然得以保留。
3.空间整合
上篇中我们可以看到:CMS垃圾收集器是“标记——清理”算法,G1从整体上来看是基于“标记—整理”算法实现的收集器。从局部上来看是基于“复制”算法实现的,但无论如何,G1在运行期间捕虎刺产生内存空间碎片,收集后能提供规整的可用内存。这种特性有利于程序的长时间运行,分配大对象是不会因为无法找到连续内存空间而提前触发下一次的GC.
4.可预测的停顿
这个是G1相对于CMS的另外一大优势,降低停顿时间是G1和CMS共同关注点,但G1除了追求低停顿外,它还能建立可预测的停顿时间模型。

具体的实现过程

1.G1会将内存划分成为多个大小相等的独立区域,G1收集器之所以能建立可预测的停顿的时间模型,是因为它可以有计划的避免在整个Java堆中进行全区域的垃圾收集。
2.G1会跟踪各个Region里面的垃圾堆积的价值大小,在后台会维护一个列表,每次根据允许的收集时间,优先回收价值最大的Region。
这种使用Region划分内存空间以及有优先级的区域回收方式,保证了G1收集器在有限的时间内可以获取尽可能高的收集效率。
如下图所示:
假设这个时候虚拟机需要分配一个Region需求,这个时候会去它的后台列表里面查询优先级,算法很复杂,在这里我假设Region1是优先级收集最低的,没多少对象。

具体过程我就简单表达:
它就会把Region1里面的还在使用对象复制到Region2中,
Region1直接释放,这个只是我们从表面看起来的效果,具体实际过程我们接下来再说。
JVM学习六.G1垃圾收集处理器详解_第1张图片
我们可以看到Region1 20%——>0%;Region2 50%——>70%.
我们可以看到这个时候Region以及被释放出来。
所以从局部看他是一个“标记-复制”算法。
当然G1的原理远远不止这么简单。

G1运作步骤

初始标记:
仅仅标记一下GC roots能直接关联到的对象,并且修改TAMS的值,让下一阶段的用户程序并发运行时,能在正确的可用的region中创建新对象,这个阶段需要停顿线程,但耗时很短。
并发标记:
从GC root开始堆对象进行可达性分歧,找出存活的对象,这个阶段耗时较长,但可与用户程序并发执行。
最终标记:
修复在并发标记期间的一些导致异常产生的数据。
筛选回收:
会对各个Region的回收价值和成本进行排序,然后根据用户所期望的GC停顿时间来制定回收计划。

CMS or G1垃圾收集器?

CMS和G1大家都了解之后,那我们到底应该选择拿一个呢?
借鉴网上大佬的一句话:
G1和CMS相比,虽然他们都立足于低停顿时间,CMS仍然是我的选择。
但是随着Oracle对G1的持续改进,G1会是最后的胜利者。
如果你现在采用的收集器没有出现问题,那就没有任何理由现在去选择G1;
如果你的应用追求低停顿,那G1现在已经可以作为一个可尝试的选择;
如果你的应用追求吞吐量,那G1并不会为你带来什么特别的好处。

参考来源:《深入理解Java虚拟机》 第二版

你可能感兴趣的:(Java虚拟机,201901)