垃圾回收之G1 GC

一.设计目标

将 STW 停顿的时间和分布,变成 可预期且可配置的

1)首先,堆不再分成年轻代和老年代,而是划分为多个(通常是 2048个)可以存放对象的小块堆区域(smaller heap regions)。 每个小块,可能一会被定义成 Eden 区,一会被指定为 Survivor 区或者Old 区。在逻辑上,所有的 Eden 区和 Survivor 区合起来 就是年轻代,所有的 Old 区拼在一起那就是老年代

2)这样划分之后,使得 G1 不必每次都去收集整 个堆空间,而是以增量的方式来进行处理: 每 次只处理一部分内存块,称为此次 GC 的回收 集(collection set)。每次 GC 暂停都会收集所 有年轻代的内存块,但一般只包含部分老年代 的内存块 。

G1 的另一项创新是,在并发阶段估算每个小堆 块存活对象的总数。构建回收集的原则是: 垃 圾最多的小块会被优先收集。这也是 G1 名称 的由来。

二.配置参数

java -Xmx1g -Xms1g -XX:-UseAdaptiveSizePolicy -XX:-UseG1GC -XX:MaxGCPauseMillis -jar gateway-server-0.0.1-SNAPSHOT.jar

-XX:+UseG1GC:启用 G1 GC;

-XX:G1NewSizePercent:初始年轻代占整个 Java Heap 的大小,默认值为 5%;

-XX:G1MaxNewSizePercent:最大年轻代占整个 Java Heap 的大小,默认值为 60%;

-XX:G1HeapRegionSize:设置每个 Region 的大小,单位 MB,需要为 1、2、4、8、16、32 中的某个值,默认是堆内存的 1/2000。如果这个值设置比较大,那么大对象就可以进入 Region 了; -XX:ConcGCThreads:与 Java 应用一起执行的 GC 线程数量,默认是 Java 线程的 1/4,减少这个参数的数值可能会提升并行回收 的效率,提高系统内部吞吐量。如果这个数值过低,参与回收垃圾的线程不足,也会导致并行回收机制耗时加长;

-XX:+InitiatingHeapOccupancyPercent(简称 IHOP):G1 内部并行回收循环启动的阈值,默认为 Java Heap的 45%。这个可 以理解为老年代使用大于等于 45% 的时候,JVM 会启动垃圾回收。这个值非常重要,它决定了在什么时间启动老年代的并行回收;

-XX:G1HeapWastePercent:G1停止回收的最小内存大小,默认是堆大小的 5%。GC 会收集所有的 Region 中的对象,但是如果 下降到了 5%,就会停下来不再收集了。就是说,不必每次回收就把所有的垃圾都处理完,可以遗留少量的下次处理,这样也降低了 单次消耗的时间;

-XX:G1MixedGCCountTarget:设置并行循环之后需要有多少个混合 GC 启动,默认值是 8 个。老年代 Regions的回收时间通常比 年轻代的收集时间要长一些。所以如果混合收集器比较多,可以允许 G1 延长老年代的收集时间。

-XX:+G1PrintRegionLivenessInfo:这个参数需要和 -XX:+UnlockDiagnosticVMOptions 配合启动,打印 JVM 的调试信息,每个 Region 里的对象存活信息。

-XX:G1ReservePercent:G1 为了保留一些空间用于年代之间的提升,默认值是堆空间的 10%。因为大量执行回收的地方在年轻代 (存活时间较短),所以如果你的应用里面有比较大的堆内存空间、比较多的大对象存活,这里需要保留一些内存。

-XX:+G1SummarizeRSetStats:这也是一个 VM 的调试信息。如果启用,会在 VM 退出的时候打印出 Rsets 的详细总结信息。 如果启用 -XX:G1SummaryRSetStatsPeriod 参数,就会阶段性地打印 Rsets 信息。

-XX:+G1TraceConcRefinement:这个也是一个 VM 的调试信息,如果启用,并行回收阶段的日志就会被详细打印出来。

-XX:+GCTimeRatio:这个参数就是计算花在 Java 应用线程上和花在 GC 线程上的时间比率,默认是 9,跟新生代内存的分配比例一 致。这个参数主要的目的是让用户可以控制花在应用上的时间,G1 的计算公式是 100/(1+GCTimeRatio)。这样如果参数设置为 9,则最多 10% 的时间会花在 GC 工作上面。Parallel GC 的默认值是 99,表示 1% 的时间被用在 GC 上面,这是因为 Parallel GC 贯 穿整个 GC,而 G1 则根据 Region 来进行划分,不需要全局性扫描整个内存堆。

-XX:+UseStringDeduplication:手动开启 Java String 对象的去重工作,这个是 JDK8u20 版本之后新增的参数,主要用于相同 String 避免重复申请内存,节约 Region 的使用。

-XX:MaxGCPauseMills:预期 G1 每次执行 GC 操作的暂停时间,单位是毫秒,默认值是 200 毫秒,G1 会尽量保证控制在这个范围 内。

三.G1 GC 的注意事项

特别需要注意的是,某些情况下 G1 触发了 Full GC,这时 G1 会退化使用 Serial 收集器来完成垃圾的清理工作,它仅仅使用单 线程来完成 GC 工作,GC 暂停时间将达到秒级别的。

1.并发模式失败 G1 启动标记周期,但在 Mix GC 之前,老年代就被填满,这时候 G1 会放弃标记周期。

解决办法:增加堆大小,或者调整周期(例如增加线程数-XX:ConcGCThreads 等)。

2.晋升失败 没有足够的内存供存活对象或晋升对象使用,由此触发了 Full GC(to-space exhausted/to-space overflow)。

解决办法:

a) 增加 –XX:G1ReservePercent 选项的值(并相应增加总的堆大小)增加预留内存量。

b) 通过减少 –XX:InitiatingHeapOccupancyPercent 提前启动标记周期。

c) 也可以通过增加 –XX:ConcGCThreads 选项的值来增加并行标记线程的数目。

3.巨型对象分配失败 当巨型对象找不到合适的空间进行分配时,就会启动 Full GC,来释放空间。 解决办法:增加内存或者增大 -XX:G1HeapRegionSize

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值