G1垃圾收集器

时间:2021-08-10 14:50:11

G1:Garbage First


特点:

1.并行与并发:G1能充分利用多CPU,多核环境下的硬件优势来缩短Stop the world停顿的时间。并行:Parallel,多个GC进程一起执行。并发:Concurrent,GC进程与用户进程一起执行。

2.分代收集:G1不需要其他垃圾收集器就能独立管理整个GC堆,但它能采用不同的方式来回收新对象与旧对象来获得更好的收集效果。

3.空间整合:G1整体来看是基于标记-整理算法实现的收集器,局部来看是基于复制算法实现的。这两种算法在运行期间都不会产生内存空间碎片。

4.可预测的停顿:能让使用者明确指定在长度M毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N毫秒。


概述

G1收集器将整个java堆划分为多个大小相等的Region,虽然还保留新生代老年代的概念,但是不是物理隔离的,它们都是一部分region的集合。

G1收集器之所以能建立可预测的停顿时间模型,是因为它可以有计划地避免在整个java堆中进行全区域的垃圾收集。G1跟踪各个Region里面的垃圾堆积的价值大小,在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region。

虽然java堆被划分成了很多Region,但这些Region彼此并不孤立,因为不同Region里的对象可能存在引用关系。那在做可达性分析的时候,是不是就要扫描整个java堆了?其实这个问题在其他收集器中也存在,老年代与新生代中的对象可能存在引用关系,如果回收新生代时,不得不扫描老年代的话,MinorGC的效率会很低。 在G1收集器中,Region之间的对象引用以及其他收集器中的新生代与老年代之间的对象引用,虚拟机都是使用Remembered Set来避免全堆扫描的。G1中每一个region都有一个与之对应的Remembered Set,虚拟机发现程序在对Reference类型的数据进行写操作时,会产生write barrier暂时中断写操作,检查引用的对象是否处于不同region中(在分待的例子中就是检查老年代中的对象是否引用了新生代中的对象),如果是,通过cardtable把相关引用信息记录到被引用对象所属的Region和RememberSet之中。


G1收集过程(可以类比CMS,有很多相似之处)

1.初始标记:标记GC Roots能直接关联到的对象,并修改TAMS(Next Top at Mark Start),让下一阶段用户程序并发运行时,能在正确可用的region中创建新对象。

2.并发标记:可达性分析。

3.最终标记:修正在并发标记期间标记产生变动的那一部分标记记录,对象记录在线程Remembered Set Logs里面。最终标记阶段需要把Remembered Set Logs的数据合并到Remembered Set中。

4.筛选回收(并发):首先对各个Region的回收价值和成本进行排序,根据用户所期望的GC停顿时间来制定回收计划。但是因为只回收一部分Region,时间是用户可控制的。