首页   快速返回

g1 GC 要点     所属分类 java
Garbage-First Garbage Collector
-XX:+UseG1GC


高吞吐、没有内存碎片、收集时间可控


新生代、老年代和永久代(JDK8去除永久代,引入元空间Metaspace)

young (eden + S0 + S1)
old/tenured
permanent

各代的存储地址(逻辑地址)连续

Region

E S O H

humongous object,H-obj

大小大于等于region一半的对象。
H-obj有如下几个特征:
H-obj直接分配到了old gen,防止反复拷贝移动。
H-obj在global concurrent marking阶段的cleanup 和 full GC阶段回收。
在分配H-obj之前先检查是否超过 initiating heap occupancy percent和the marking threshold, 
如果超过的话,就启动global concurrent marking,提早回收,防止 evacuation failures 和 full GC。
大对象占用连续分区
Continues Humongous



Region大小设置 -XX:G1HeapRegionSize
1M到32M,且是2的指数

SATB 
Snapshot-At-The-Beginning

GC开始时对存活对象的一个快照 通过Root Tracing得到 维持并发GC的正确性
三色标记算法

白:对象没有被标记到,标记阶段结束后,会被当做垃圾回收掉。
灰:对象被标记了,但是它的field还没有被标记或标记完。
黑:对象被标记了,且它的所有field也被标记完了。


并发阶段 Mutator和GC线程,同修改对象 ,会出现白对象漏标的情况
Mutator线程 也叫应用线程

Region中有两个top-at-mark-start(TAMS)指针,分别为prevTAMS和nextTAMS。

write barrier 

float garbage


RSet Remembered Set
CSet Collection Set

Card Table


每个Region都有一个RSet,RSet记录了其他Region中的对象引用本Region中对象的关系,属于points-into结构(谁引用了我的对象)。
Card Table则是一种points-out(我引用了谁的对象)的结构,每个Card 覆盖一定范围的Heap(一般为512Bytes)。

G1的RSet是在Card Table的基础上实现的:
每个Region会记录下别的Region有指向自己的指针,并标记这些指针分别在哪些Card的范围内。 
这个RSet其实是一个Hash Table,Key是别的Region的起始地址,Value是一个集合,里面的元素是Card Table的Index。


RSet、Card和Region的关系



每个Region被分成多个Card,不同Region的Card会相互引用,蓝色实线表示points-out关系,
Region2的RSet中,记录Region1的Card,红色虚线表示 points-into。

RSet中的引用关系靠post-write barrier和Concurrent refinement threads来维护

void oop_field_store(oop* field, oop new_value) {
  pre_write_barrier(field);             // pre-write barrier: for maintaining SATB invariant
  *field = new_value;                   // the actual store
  post_write_barrier(field, new_value); // post-write barrier: for tracking cross-region reference
}


post-write barrier记录了跨Region的引用更新,更新日志缓冲区则记录了那些包含更新引用的Cards。
一旦缓冲区满了,Post-write barrier就停止服务会由Concurrent refinement threads处理这些缓冲区日志。


YGC 只需要选定年轻代 region的RSet作为根集,这些RSet记录了old->young的跨代引用,避免扫描整个老年代。 
mixed gc 也不需要扫描整个老年代

Pause Prediction Model 停顿预测模型
G1 uses a pause prediction model to meet a user-defined pause time target 
and selects the number of regions to collect based on the specified pause time target.

响应时间优先   与CMS区别  可设置 期望停顿时间 -XX:MaxGCPauseMillis 默认200MS

G1根据这个模型统计计算出来的历史数据来预测本次收集需要选择的Region数量,尽量满足用户设定的目标停顿时间。

停顿预测模型以衰减标准偏差为理论基础实现


两种GC模式,Young GC和Mixed GC

Young GC:选定所有年轻代里的Region。通过控制年轻代的region个数,即年轻代内存大小,来控制young GC的时间开销。

Mixed GC:选定所有年轻代里的Region,外加根据global concurrent marking统计得出收集收益高的若干老年代Region。
在用户指定的开销目标范围内尽可能选择收益高的老年代Region。


Mixed GC不是full GC,只能回收部分老年代Region

如果老年代被填满 使用serial old GC(full GC)来收集整个堆

global concurrent marking 四个步骤


初始标记(initial mark,STW)。它标记了从GC Root开始直接可达的对象。
并发标记(Concurrent Marking)。这个阶段从GC Root开始对heap中的对象标记,标记线程与应用程序线程并行执行,并且收集各个Region的存活对象信息。
最终标记(Remark,STW)。标记那些在并发标记阶段发生变化的对象,将被回收。
清除垃圾(Cleanup)。清除空Region(没有存活对象的),加入到free list。

第一阶段initial mark 共用了Young GC的暂停,复用root scan操作



-XX:G1HeapWastePercent:G1不会回收的内存大小,默认是堆大小的5% ,GC会收集所有的Region,如果值达到5%,就会停下来不再收集了
-XX:G1ReservePercent:保留一些空间用于年代之间的提升,默认值是堆空间的10% 

-XX:G1ReservePercent=10
Sets the percentage of reserve memory to keep free so as to reduce the risk of to-space overflows. The default is 10 percent. 
When you increase or decrease the percentage, make sure to adjust the total Java heap by the same amount. 
This setting is not available in Java HotSpot VM, build 23.


-XX:G1HeapRegionSize=n	设置Region大小,并非最终值
-XX:MaxGCPauseMillis	设置暂停目标时间,默认200ms,期望值
-XX:G1NewSizePercent	新生代最小值,默认值5%
-XX:G1MaxNewSizePercent	新生代最大值,默认值60%
-XX:ParallelGCThreads	并行GC线程数
-XX:ConcGCThreads=n	并发标记阶段,并行执行的线程数
-XX:InitiatingHeapOccupancyPercent	设置触发标记周期的堆占用率阈值。默认45%。整个堆

IHOP

-XX:G1MixedGCLiveThresholdPercent=65

Sets the occupancy threshold for an old region to be included in a mixed garbage collection cycle. 
The default occupancy is 65 percent. This is an experimental flag. 

-XX:G1MixedGCCountTarget=8
Sets the target number of mixed garbage collections after a marking cycle to collect old regions 
with at most G1MixedGCLIveThresholdPercent live data. 
The default is 8 mixed garbage collections. 
The goal for mixed collections is to be within this target number. 
This setting is not available in Java HotSpot VM, build 23.

-XX:G1OldCSetRegionThresholdPercent=10
Sets an upper limit on the number of old regions to be collected during a mixed garbage collection cycle. 
The default is 10 percent of the Java heap. This setting is not available in Java HotSpot VM, build 23.




GC日志关键信息


region size 1024K, 172 young (176128K), 13 survivors (13312K)

GC原因
[GC pause (G1 Evacuation Pause) (young)

[Parallel Time: 8.1 ms, GC Workers: 4]

[G1Ergonomics (Concurrent Cycles) request concurrent cycle initiation, reason: occupancy higher than threshold, occupancy: 1449132032 bytes, allocation request: 579608 bytes, 
threshold: 1449551430 bytes (45.00 %), source: concurrent humongous allocation]



Garbage First Garbage Collector Tuning
https://www.oracle.com/technetwork/articles/java/g1gc-1984535.html

上一篇     下一篇
jvm设置滚动记录GC日志

基于数据库的分布式锁设计

prometheus集成grafana实现可视化

四种引用及WeakHashMap介绍

软引用弱引用及引用队列实战例子

grafana基本概念