G1收集器(-XX:+UseG1GC)
G1(Garbage-First)是一款面向服务器的垃圾收集器,主要针对配备多颗处理器及大容量内存的机器.以极高概率满足GC
停顿时间要求的同时,还具备高吞吐量性能特征.
G1将Java堆划分为多个大小相等的独立区域(Region),JVM最多可以有2048个Region。
一般Region大小等于堆大小除以2048,比如堆大小为4096M,则Region大小为2M,当然也可以用参数"-
XX:G1HeapRegionSize"手动指定Region大小,但是推荐默认的计算方式。
G1保留了年轻代和老年代的概念,但不再是物理隔阂了,它们都是(可以不连续)Region的集合。
默认年轻代对堆内存的占比是5%,如果堆大小为4096M,那么年轻代占据200MB左右的内存,对应大概是100个
Region,可以通过“-XX:G1NewSizePercent”设置新生代初始占比,在系统运行中,JVM会不停的给年轻代增加更多
的Region,但是最多新生代的占比不会超过60%,可以通过“-XX:G1MaxNewSizePercent”调整。年轻代中的Eden和
Survivor对应的region也跟之前一样,默认8:1:1,假设年轻代现在有1000个region,eden区对应800个,s0对应100
个,s1对应100个。
一个Region可能之前是年轻代,如果Region进行了垃圾回收,之后可能又会变成老年代,也就是说Region的区域功能
可能会动态变化。
G1垃圾收集器对于对象什么时候会转移到老年代跟之前讲过的原则一样,唯一不同的是对大对象的处理,G1有专门分配
大对象的Region叫Humongous区,而不是让大对象直接进入老年代的Region中。在G1中,大对象的判定规则就是一
个大对象超过了一个Region大小的50%,比如按照上面算的,每个Region是2M,只要一个大对象超过了1M,就会被放
入Humongous中,而且一个大对象如果太大,可能会横跨多个Region来存放。
Humongous区专门存放短期巨型对象,不用直接进老年代,可以节约老年代的空间,避免因为老年代空间不够的GC开
销。
FullGC的时候除了收集年轻代和老年代之外,也会将Humongous区一并回收。
G1收集器一次GC的运作过程大致分为以下几个步骤:
初始标记(initialmark,STW):暂停所有的其他线程,并记录下gcroots直接能引用的对象,速度很快;