G1垃圾收集器
G1是一个面向服务端的JVM垃圾收集器,适用于多核处理器、大内存容量的服务端系统。 它满足短时间停顿的同时达到一个高的吞吐量。从JDK 9开始,G1成为默认的垃圾回收器。
当应用有以下任何一种特性时非常适合用G1:
- Full GC持续时间太长或者太频繁
- 对象的创建速率和存活率变动很大
- 应用不希望停顿时间长(长于0.5s甚至1s)
G1对Heap的划分
G1按固定大小把内存划分为很多小区域(region),这个堆大概有2000多块;在逻辑上,某些小区域构成Eden,某些构成Survivor,某些构成老年代,这些小区域物理上是不相连的,并且构成新生代和老年代的区域可以动态改变。
可以通过命令行参数
-XX:NewRatio=n
来配置老年代和新生代的比例,默认为2,即比例为2:1;-XX:SurvivorRatio=n
则可以配置Eden与Survivor的比例,默认为8。
Young GC
当Eden区的空间占满之后,会触发Young GC,G1将Eden和Survivor中存活的对象拷贝到Survivor,或者直接晋升到Old Region中。Young GC的执行是多线程并发的,期间会停顿所有的用户线程(STW)。
Old GC
当堆空间的占用率达到一定阈值后会触发Old GC(阈值由命令参数-XX:InitiatingHeapOccupancyPercent
设定,默认值45),Old GC分五个步骤完成:
初始标记(Initial Mark,STW)
对Survivor区域扫描,标记出可能拥有老年代对象引用的根区域(Root Region),该阶段附属于一次Young GC的最后阶段,所以是STW。在GC日志中会被记录为GC pause (young)(inital-mark)
根区域扫描(Root Region Scan)
从上一阶段标记的根区域中,标记所有拥有老年代对象引用的存活对象,这是一个并发的过程,而且必须在进行下一次Young GC之前完成
并发标记(Concurrent Marking)
从上一阶段标记的存活对象开始,并发地跟踪所有可达的老年代对象,期间可以被Young GC打断
最终标记(Remark,STW)
G1并行地跟踪在上面阶段经过更新的存活对象,找到未被标记的存活的对象,这是一个STW的阶段,会用到一个初始快照(SATB)算法。在此期间完全空闲的区域会被直接重置回收。
复制/清除(Copying/Cleanup,STW)
- G1统计存活对象和完全空闲的区域,完全空闲区域将被重置回收
- 执行清理RSet的操作
- 将存活对象复制到新的未被占用的区域。执行这一步时可以只对新生代操作,这时G1将其记录为
[GC pause (young)]
;也可对新生代和一部分老年代都进行处理,这时被记录为[GC Pause (mixed)]
,这些老年代要根据其“存活度”去选择。
G1相关的命令
java命令行参数
Option | Description |
---|---|
-XX:+UseG1GC | Use the Garbage First (G1) Collector |
-XX:MaxGCPauseMillis=n | Sets a target for the maximum GC pause time. This is a soft goal, and the JVM will make its best effort to achieve it. |
-XX:InitiatingHeapOccupancyPercent=n | Percentage of the (entire) heap occupancy to start a concurrent GC cycle. It is used by GCs that trigger a concurrent GC cycle based on the occupancy of the entire heap, not just one of the generations (e.g., G1). A value of 0 denotes 'do constant GC cycles'. The default value is 45. |
-XX:NewRatio=n | Ratio of old/newgeneration sizes. The default value is 2. |
-XX:SurvivorRatio=n | Ratio of eden/survivor space size. The default value is 8. |
-XX:MaxTenuringThreshold=n | Maximum value for tenuring threshold. The default value is 15. |
-XX:ParallelGCThreads=n | Sets the number of threads used during parallel phases of the garbage collectors. The default value varies with the platform on which the JVM is running. |
-XX:ConcGCThreads=n | Number of threads concurrent garbage collectors will use. The default value varies with the platform on which the JVM is running. |
-XX:G1ReservePercent=n | Sets the amount of heap that is reserved as a false ceiling to reduce the possibility of promotion failure. The default value is 10. |
-XX:G1HeapRegionSize=n | With G1 the Java heap is subdivided into uniformly sized regions. This sets the size of the individual sub-divisions. The default value of this parameter is determined ergonomically based upon heap size. The minimum value is 1Mb and the maximum value is 32Mb. |
查看JVM默认的垃圾回收器
java -XX:+PrintCommandLineFlags -version
如
-XX:G1ConcRefinementThreads=4 -XX:InitialHeapSize=134217728 -XX:MaxHeapSize=2147483648 -XX:+PrintCommandLineFlags -XX:ReservedCodeCacheSize=251658240 -XX:+SegmentedCodeCache -XX:+UseCompressedClassPointers -XX:+UseCompressedOops -XX:+UseG1GC
java version "9.0.4"
Java(TM) SE Runtime Environment (build 9.0.4+11)
Java HotSpot(TM) 64-Bit Server VM (build 9.0.4+11, mixed mode)
查看JVM当前堆情况
jmap -heap pid
如
jmap -heap 20932
Attaching to process ID 20932, please wait...
Debugger attached successfully.
Server compiler detected.
JVM version is 25.131-b11
using thread-local object allocation.
Garbage-First (G1) GC with 4 thread(s)
Heap Configuration:
MinHeapFreeRatio = 40
MaxHeapFreeRatio = 70
MaxHeapSize = 4164943872 (3972.0MB)
NewSize = 1363144 (1.2999954223632812MB)
MaxNewSize = 2498756608 (2383.0MB)
OldSize = 5452592 (5.1999969482421875MB)
NewRatio = 2
SurvivorRatio = 8
MetaspaceSize = 21807104 (20.796875MB)
CompressedClassSpaceSize = 1073741824 (1024.0MB)
MaxMetaspaceSize = 17592186044415 MB
G1HeapRegionSize = 1048576 (1.0MB)
Heap Usage:
G1 Heap:
regions = 3972
capacity = 4164943872 (3972.0MB)
used = 2132264664 (2033.4860458374023MB)
free = 2032679208 (1938.5139541625977MB)
51.19551978442604% used
G1 Young Generation:
Eden Space:
regions = 829
capacity = 2317352960 (2210.0MB)
used = 869269504 (829.0MB)
free = 1448083456 (1381.0MB)
37.51131221719457% used
Survivor Space:
regions = 9
capacity = 9437184 (9.0MB)
used = 9437184 (9.0MB)
free = 0 (0.0MB)
100.0% used
G1 Old Generation:
regions = 1254
capacity = 1741684736 (1661.0MB)
used = 1253557976 (1195.4860458374023MB)
free = 488126760 (465.51395416259766MB)
71.9738739215775% used
19747 interned Strings occupying 1885184 bytes.