66.G1垃圾收集器、优势与缺点、参数设置、使用场景
1.G1
概述
-
为什么有了前面几个强大的垃圾收集器,还需要
Garbage First(G1) GC
?
随着应用程序所应对的业务越来越庞大、复杂,前面几款垃圾收集器已经不能满足实际的需要,所以出现了G1
。 -
G1
是在延迟可控的情况下,获得尽可能高的吞吐量,所以才担当起“全功能收集器”的重任与期望。(全功能收集器的意思是它既负责新生代的垃圾回收又负责老年代的垃圾回收) -
G1
收集器将堆内存划分为很多不想关的区域(Region)
(物理上可以是不连续的空间),使用不同的Region
来表示Eden
,S0
区,S1
区,老年代等等。 -
G1
有计划的避免在整个Java
堆中进行全区域的垃圾收集,G1
会跟踪各个Region
里面的垃圾堆积的价值大小(回收所获得的空间大小以及回收所需要的时间经验值),在后台维护一个优先列表,每次根据允许的收集时间,优先回收价值最大的Region
。 -
G1
在JDK7
中正式启用,但不是默认的垃圾收集器,在JDK9
中成为了默认的垃圾收集器,取代了CMS
以及Parallel + Parallel Old
组合。在JDK7
以及JDK8
中,可以使用-XX:+UseG1GC
来启用。 -
G1
将堆空间划分为若干个区域(Region
),各个region
可以是Eden
区,Survivor
区以及Old
区等。
2.G1
的优势与缺点
优势:
- 并行与并发 - 多个垃圾收集线程同时工作(并行),垃圾收集线程与用户线程交替执行(并发)。
- 分代收集 -
G1
将堆空间划分为若干个区域(Region
),这些区域中包含了逻辑上的年轻代和老年代。它不要求年轻代,老年代是连续的。同时,G1
同时兼顾年轻代和老年代的垃圾回收,其他的垃圾收集器,要么工作在年轻代,要么工作在老年代。 - 空间整合(内存碎片整理) -
G1
内存回收使用Region
作为基本单位,Region
之间使用的是复制算法,能够对内存空间进行整理。 - 可预测的停顿时间模型 - 可以让用户明确指定在一个长度为
M
毫秒的时间片段内,消耗在垃圾收集上的时间不得超过N
毫秒。
缺点:
相比于CMS
,G1
还不具备全方位、压倒性优势。比如,G1
为了垃圾收集产生的内存占用
以及程序运行时的额外执行负载
都比CMS
要高。
3.G1
参数设置
-XX:G1HeapRegionSize
设置每个region
的大小,值只能是2
的n
次方(1,2,4,8,16,32
),范围是1MB
到32MB
。-XX:MaxGCPauseMillis
设置期望达到(JVM
会尽力实现,但不保证)的最大GC
停顿时间,默认是200ms
。 这个参数如果设置的过小,会导致一次回收的region
个数减少,回收的垃圾对象减少(因为设置的垃圾线程工作的时间减少了),如果产生垃圾的速度很快,可能会导致Full GC
。-XX:ParallelGCThread
设置STW
的时候并行的垃圾线程数量。-XX:ConcGCThreads
设置用户线程与垃圾收集线程并发的时候,垃圾收集线程的线程数量
通常使用G1
收集器,不需要那么多的参数配置。只需要进行下图所示的3
步。其他的参数,G1
会自动调节或使用默认的参数。