GC算法之G1-PART IV
G1 GC 在收集暂停期间回收其大部分堆区域。唯一的例外是多阶段并发标记周期的清理阶段。在清理阶段,如果 G1 GC 遇到纯垃圾填充区域,它可以立即回收这些区域,并将它们返回到空闲区域链表;因此,释放这些区域不必等待下一次垃圾收集暂停。
在新生代收集期间,G1 GC 暂停应用程序线程以将活动对象从新生代区域移动到幸存者区域或将它们提升到老年代区域或两者兼而有之。对于mix collection,G1 GC 额外地将活动对象从最(因为缺少更好的术语)“高效”的旧区域移动到空闲区域,这些区域成为老年代的一部分。
我们在这里提到的“效率”完全取决于活跃度计算,因此只是收集一个区域的成本。例如,一个 old region 的收集比其他更昂贵的 old region 耗时更少,被认为是一个“高效”的 region。
年轻代
大多数内存分配,将落入指定线程的 TLAB(本地分配缓冲区)。除了少数例外,例如对象太大而无法放入分配线程的本地分配缓冲区(也称为 TLAB)但小于被认为是“Humongous ”对象,当然还有“Humongous ”对象本身。
TLAB 支持更快的内存分配,因为相应的Java 线程能够以无锁方式进行分配。
除非在命令行中明确指定,否则当前的年轻代大小是根据初始年轻代大小,最大年轻代大小,应用程序的暂停时间目标 (-XX:MaxGCPauseMillis)来确定的。
从 JDK 8u45 开始,上述三个属性的默认值如下:
- initial young generation size (-XX:G1NewSizePercent) : 总 Java 堆的 5%
- maximum young generation size (-XX:G1MaxNewSizePercent) : 总 Java 堆的 60%
- pause time goal of the application (-XX:MaxGCPauseMillis) : 200ms
如果用户设置 -Xmn 或相关的年轻代大小调整命令行选项,例如 -XX:NewRatio,G1 GC 可能无法根据暂停时间目标调整年轻代大小,因此暂停时间目标(XX:MaxGCPauseMillis)可能成为没有实际意义的选项。
JVM通常为堆划分2048个region,Heap region size = Heap size/region's count (Heap size/2048)。
可以通过-XX:G1HeapRegionSize=n来设置heap region size。