G1 GC,全称Garbage-First Garbage Collector,在jdk6版本除了体验版,jdk7正式推出,jdk9钟,被提倡为默认GC
1. G1适用场景
G1适合作为服务端垃圾收集器,应用在多处理器和大内存的条件下,可以实现高吞吐量的同时,尽可能满足垃圾收集较短可控的暂停时间,主要针对以下场景设计
2. G1 数据模型
2.1 分区Region
传统的GC将内存划分为新生代,老年代,永久代(JDK8取消了永久代),传统划分的各代存储地址是连续的
G1的各代存储地址是不连续的,每一代都使用了n个不连续region,每个region占有一块连续的虚拟内存,
每一个分配的Region,都可以分成两个部分,已分配的和未被分配的。它们之间的界限被称为top。总体上来说,把一个对象分配到Region内,只需要简单增加top的值。
G1收集器会维护一个空间Region的链表,每次回收的Region都会加入这个链表中,每次只有一个Region处于被分配状态(current region)。多线程情况下用TLABs为每个线程分配Buffer,即为每个线程分配一个Buffer,线程分配内存都在这个Buffer内分配
-XX:G1HeapRegionSize=n
可指定分区大小(1MB~32MB,且必须是2的幂),默认将整堆划分为2048个分区。
2.2 RSet(RememberSet)、CT(CardTable)和CSet(CollectionSet)
在普通的分代收集(如CMS)中,新生代收集后,部分对象需要从新生代转移到老年代,而引用该对象的记录也需要更新,这个过程需要采用的copying算法移动对象,所以要更新引用为对象的新地址,通常叫做remembered set(简称RS)。
因为每次G1GC都是针对一部分Region回收, 所以回收时需要确定该Region的对象被哪些其他Region的对象引用着,而在G1中,CardTable是一种remembered set, 一个card代表一个范围的内存,目前采用512bytes表示一个card,cardtable就是一个byte数组,每个Region有自己的Cardtable。
维护remembered set需要mutator线程在可能修改跨Region的引用的时候通知collector, 这种方式通常叫做write barrier(和GC中的Memory Barrier不同), 每个线程都会有自己的remembered set log,相当于各自的修改的card的缓冲buffer,除此之外还有全局的buffer,mutator自己的remember set buffer满了之后会放入到全局buffer中,然后创建一个新的buffer。
逻辑上说每个Region都有一个RSet,RSet记录了其他Region中的对象引用本Region中对象的关系,但在G1中,并没有使用point-out,这是由于一个分区太小,分区数量太多,如果用point-out,会造成大量扫描浪费,有些根本不需要GC的分区引用也扫描了。所以G1使用points-into结构(谁引用了我的对象)。而Card Table则是一种points-out(我引用了谁的对象)的结构,每个Card 覆盖一定范围的Heap(一般为512Bytes)。G1的RSet是在Card Table的基础上实现的:每个Region会记录下别的Region有指向自己的指针,并标记这些指针分别在哪些Card的范围内。 这个RSet其实是一个Hash Table,Key是别的Region的起始地址,Value是一个集合,里面的元素是Card Table的Index。
RSet、CardTable和Region的关系(出处)
上图中有三个Region,每个Region被分成了多个Card,在不同Region中的Card会相互引用,Region1中的Card中的对象引用了Region2中的Card中的对象,蓝色实线表示的就是points-out的关系,而在Region2的RSet中,记录了Region1的Card,即红色虚线表示的关系,这就是points-into。
3. G1 GC过程
G1提供了两种GC模式,Young GC和Mixed GC,两种均是完全Stop The World的。
3.1 G1 YoungGC
3.2 G1 Mix GC
在G1 GC中,它主要是为Mixed GC提供标记服务的,并不是一次GC过程的一个必须环节。global concurrent marking的执行过程分为五个步骤:
活跃度越低,代表回收的效率越高,越值得优先回收。
2. 复制、清理阶段(Copying/Cleanup Phase)
年轻代、老年代在这个阶段同时被回收掉。老年代被回收的region,是根据这个region的存活度来选择的。
本章节简单介绍了G1的概念,数据模型和GC过程,下一章节会对G1相关算法进行一些讲解总结。