G1 收集器

G1 是jdk7之后的最新的垃圾收集器,目的是取代CMS,达到更小的pause time更高的throughput的目的,能够压缩(CMS不行),更少的停顿(CMS两次),并且可以让用户配置更希望的停顿(pause time goal 不准)
G1的原理是,将整个heap分成大小相等的一个个region(每个region的大小1-32M,原理是region个数在2048左右,可以通过参数-XX: G1HeapRegionSize=n来配置),然后通过扫描各个region,找出garbage最多的那些,进行回收(原理是,该region中的对象与其他region关联的越少就是garbage越多的),即Garbage First
适用于以下应用环境:
1. 超过50%的heap是被live data占用
2. 对象被回收或提升的比例变化明显(??)
3. 应用不需要太长的GC或者GC暂停(超过0.5-1s)
具体的垃圾收集,G1仍可分为young和mixed(young和old一起),对于G1来说heap中没有严格的young和old的划分(动态变化的,如果不通过参数设置死的话),
Card Table:在回收region时,可能存在对象的引用关系不在本次回收search的这些regions中(比如old到young的引用),那么这些引用的pointer会被存放在每个region的Remember Set(RSet)中,等到压缩复制的时候一起移入新的空region中
G1在young回收触发时机:young full,sweep的对象是(上次Marking Cycle中标记的那些region对象),然后对这些对象该清理的清理,该移入survivor的移入,该提升old的提升。
G1的mixed回收,也就是full GC,触发时机:根据配置的内部机制,比如根据pause time goal(MaxGCPauseMillis(200)/ GCPauseIntervalMillis(0))决定,或者-XX:InitiatingHeapOccupancyPercent=<N>(默认45)参数决定,在mixed回收触发之前,是整个G1的Marking Cycle,包括以下几步:
1. 初始标记,G1标记roots对象(同时一个普通的STW的young回收触发)
2. roots对象扫描,G1扫描survivor和old之间的引用,标记live object(old),并发(不STW),同时必须在下一次young GC之前完成
3. remark,重新扫描SATB(snapshot-at-the-beginning)完成整个标记,标记遗漏的live object
4. cleanup,STW, 部分并发,压缩拷贝移动,释放新的空regions,其中STW的操作是,标记空白region及下一次回收的old regions的过程
注:SATB,是指在marking cycle开始的时候,G1对于HEAP的快照,整个扫描都会基于这个快照的结果,可能会产生浮动垃圾
G1中的pause:
1. 发生在复制移动时(live object from region1 to region2),young GC和old GC都会发生
2. 在初始标记时发生(这被看做是young GC的一部分)
3. 在cleanup的时候发生

大对象处理
在G1中,对于超过0.5个region size的对象是大对象,对于大对象不会移动,只会清理,并且直接分配到old中

异常:
Overflow和Exhausted 日志信息, 在G1回收,打开GC日志,出现下列信息:
• 924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space exhausted), 0.1957310 secs]
• 924.897: [GC pause (G1 Evacuation Pause) (mixed) (to-space overflow), 0.1957310 secs]
原因: survivor空间不够,或者old不够不能提升
解决:
1. 提升survivor大小,通过参数:-XX:G1ReservePercent
2. 加快回收频率,通过参数-XX:InitiatingHeapOccupancyPercent
3. 增加回收的线程,通过参数:-XX:ConcGCThreads

可用配置:
Option and Default Value Option
-XX:G1HeapRegionSize=n 初始设置region大小,1-32M,保证heap中大概2048个region
-XX:MaxGCPauseMillis=200 最大的GC停顿时间200ms
-XX:G1NewSizePercent=5 * heap中YOUNG最小的比列,默认5
-XX:G1MaxNewSizePercent=60 * heap中YOUNG最大的比例,默认60
-XX:ParallelGCThreads=n STW时工作线程数,跟处理器个数一致(8个及以下时),超过8个时,可以设置为5/8处理器数,在SPARC下,可以设置为5/16
-XX:ConcGCThreads=n 并发标记线程数,设置为ParallelGCThreads的1/4
-XX:InitiatingHeapOccupancyPercent=45 触发marking cycle的heap占用大小,默认45%
-XX:G1MixedGCLiveThresholdPercent=65 触发mixed GC的heap占用大小,65%默认
-XX:G1HeapWastePercent=10 设置您愿意浪费的堆百分比。如果可回收百分比小于堆废物百分比,Java HotSpot VM 不会启动混合垃圾回收周期。默认值是 10%。
-XX:G1MixedGCCountTarget=8 mixed GC的上限次数,与G1MixedGCLIveThresholdPercent参数合用,默认8
-XX:G1OldCSetRegionThresholdPercent=10 设置混合垃圾回收期间要回收的最大旧区域数。默认值是 Java 堆的 10%
-XX:G1ReservePercent=10 设置作为空闲空间的预留内存百分比,以降低目标空间溢出的风险。默认值是 10%。增加或减少百分比时,请确保对总的 Java 堆调整相同的量。
注:带* 是实验性参数,必须对其解锁之后才能使用
解锁:显示设置-XX:+UnlockExperimentalVMOptions
java -XX:+UnlockExperimentalVMOptions -XX:G1NewSizePercent=10 -XX:G1MaxNewSizePercent=75  G1test.jar

调优G1,建议:
1. 不设置young大小,避免使用 -Xmn 选项或 -XX:NewRatio 等其他相关选项显式设置年轻代大小。固定年轻代的大小会覆盖暂停时间目标。
2. pause time goal,G1是增量垃圾回收器,暂停统一,G1的吞吐量目标是90%的应用时间,10%的GC时间,因此尽量不要设置太过严格的目标(和吞吐量垃圾回收器相比,99%应用,1%GC)
3. 控制mixed GC,通过各种参数
G1 GC 是区域化、并行-并发、增量式垃圾回收器,相比其他 HotSpot 垃圾回收器,可提供更多可预测的暂停。增量的特性使 G1 GC 适用于更大的堆,在最坏的情况下仍能提供不错的响应。G1 GC 的自适应特性使 JVM 命令行只需要软实时暂停时间目标的最大值以及 Java 堆大小的最大值和最小值,即可开始工作





你可能感兴趣的:(收集器)