Garbage First(简称G1)收集器是垃圾收集器技术发展历史上的里程碑式的成果,基于Region的内存布局,面向整个Java堆进行垃圾收集,且用户可以指定自己预期的停顿时间。
在G1之前的垃圾收集器,一般只针对某个特定的分代(FULL GC时除外),要么面向新生代,要么面向老年代。虽然G1的设计也是基于分代收集的思想,但是由于使用了基于Region的内存布局,弱化了分代的概念,垃圾回收的衡量标准不再是它属于哪个分代,而是哪块内存中存放的垃圾数量最多,回收收益最大。进行垃圾回收时,G1会把决定回收的那一部分Region的存活对象复制到空的Region中,再清理掉整个旧Region的全部空间.
G1视角下的堆内存布局
G1之前的垃圾收集器,堆内存一般被分为新生代和老年代,年轻代又分为Eden区和两个Survivor区,不同分代和分区之间的空间大小比例通过参数指定。
G1垃圾收集器将连续的Java堆划分为多个大小相等的独立区域(Region),每一个Region都可以根据需要,扮演新生代的Eden空间、Survivor空间,或者老年代空间。
Region中有一类特殊的Humongous区域,专门用来存储大对象。G1认为只要大小超过了一个Region容量一半的对象即可判定为大对象。每个Region的大小可以通过参数-XX:G1HeapRegionSize设定,取值范围为1MB~32MB,且应为2的N次幂。
对于那些超过了整个Region容量的超级大对象, 将会被存放在N个连续的Humongous Region之中,G1的大多数行为都把Humongous Region作为老年代的一部分来进行看待。
Young GC与Mixed GC
G1收集器主要有 Young GC 和 Mixed GC两种模式。
Young GC
选定所有新生代里的Region。通过控制新生代的region个数,即新生代内存大小,来控制young GC的时间开销。(复制回收算法) G1算法将堆划分为若干个区域(Region),它仍然属于分代收集器。不过,这些区域的一部分包含新生代,新生代的垃圾收集依然采用暂停所有应用线程的方式,将存活对象拷贝到老年代或者Survivor空间。老