一.简单介绍
官方文档描述:
The Garbage-First (G1) collector is a server-style garbage collector, targeted for multi-processor machines with large memories. It meets garbage collection (GC) pause time goals with a high probability, while achieving high throughput. The G1 garbage collector is fully supported in Oracle JDK 7 update 4 and later releases. The G1 collector is designed for applications that:
Can operate concurrently with applications threads like the CMS collector.
Compact free space without lengthy GC induced pause times.
Need more predictable GC pause durations.
Do not want to sacrifice a lot of throughput performance.
Do not require a much larger Java heap.
G1 is planned as the long term replacement for the Concurrent Mark-Sweep Collector (CMS). Comparing G1 with CMS, there are differences that make G1 a better solution. One difference is that G1 is a compacting collector. G1 compacts sufficiently to completely avoid the use of fine-grained free lists for allocation, and instead relies on regions. This considerably simplifies parts of the collector, and mostly eliminates potential fragmentation issues. Also, G1 offers more predictable garbage collection pauses than the CMS collector, and allows users to specify desired pause targets.
可以看出,G1垃圾收集器即Garbage-First垃圾收集器,是JDK7之后作为CMS垃圾收集器的长期支持的替代品,它是为了一下优点:
- 多核的并发处理器机器
- 相对于CMS可以减少空间碎片和垃圾清理时间
- 可以使得垃圾清理时间变得可预测
- 不会造成大量吞吐量的损失
- 不需要更大的Java堆
G1相对于CMS有以下优点:
- 不会产生太多的内存碎片空间
- 使用Region区域来替代新时代、老年代的划分
- CMS只针对于老年代进行回收,而G1对整个空间进行回收,以垃圾回收作为第一要务
- 可以设置预测的垃圾回收时间
G1垃圾收集器在JDK 9中被设置为了默认的垃圾收集器。在低级的JDK版本中,可以通过:-XX:+UseG1GC
参数来启用G1垃圾收集器。
二.垃圾回收区域变化
通常,老款的垃圾收集器如Serial、ParNew、CMS等垃圾收集器在垃圾收集过程中,会将Java堆划分成新生代、老年代和永久代这三块区域并分别对其进行回收:
但是G1垃圾收集器采用了不同的区域划分形式,它将Java堆内存划分成了一块一块等大的连续空间,并且每块空间都被标识成了不同的颜色和字母,例如E(Eden)、O(Old)、S(Servivor)等:
三.如何保证在预测时间内完成垃圾收集
G1建立了一个可预测的内存回收模型,它通过跟踪每个区域的回收价值的多少以及空间空闲大小来维护一个回收价值列表,根据这个列表来优先回收掉回收价值最大的区域Region。
G1使用了一个全局标识来表明哪些区域需要被回收,当该区域范围有大量的空闲空间时就会对这个范围内可以回收的区域立即进行回收,这样就使得内存空间碎片率降低,并且也达到了G1的目标。在垃圾收集过程中的停顿时间是可控等
四.垃圾收集的过程
G1垃圾收集器的垃圾收集过程和CMS垃圾收集器类似,可分为初始标记
、兵法标记
、重新标记
和筛选回收
这四个阶段,其中并发标记
与筛选回收
伴随着用户线程一起进行,不需要stw。
1.初始标记
stw,标记GC ROOTS无法关联到的对象。用时很短。
2.并发标记
与用户线程同时执行,将初始标记中所获取到的GC ROOTS对象进行追踪,找到需要回收的对象和不需要回收的对象。用时最长。
3.重新标记
stw,这一步是为了标记到在并发标记中,用户线程所产生的新的可回收对象。用时较短。
4.筛选回收
与用户线程同时执行,通过对区域的回收价值列表以及预测回收时间的综合分析,对可回收的区域进行筛选并回收掉,采用的是复制算法。用时为用户掉预测回收时间。这里的耗时是用户设置的最大垃圾回收时间,可通过-XX:MaxGCPauseMillis=parseMIlls
来设置。
Thanks
- https://www.breakyizhan.com/javamianshiti/2861.html
- https://www.oracle.com/technetwork/tutorials/tutorials-1876574.html#t2