java g1垃圾收集器优化参考

本文深入探讨了G1垃圾收集器在Java应用中的使用,旨在提供低延迟解决方案。G1适用于内存大于6GB的系统,目标是保持GC暂停时间小于0.5秒。内容涵盖G1的YGC、MixedGC、FullGC类型及其触发条件,以及最佳实践,如避免设置年轻代大小、设置最大暂停时间等。此外,文章还讨论了如何应对转移失败、新生代优化和老年代管理,提供了相关参数调整建议,并分析了垃圾收集日志中的常见问题。

1. G1适用场景

G1从jdk7开始,jdk9被设为默认垃圾收集器;在jdk8就需要指定参数配置,目标就是彻底替换掉CMS。

G1的首要目标是为需要大量内存的系统提供一个保证GC低延迟的解决方案,也就是说堆内存最低在6GB及以上,稳定和可预测的暂停时间小于0.5秒。
如果应用程序具有如下的一个或多个特征,那么将垃圾收集器从CMS或ParallelOldGC切换到G1将会大大提升性能:
(1)Full GC 次数太频繁或者消耗时间太长;
(2)受够了太长的垃圾回收或内存整理时间(0.5-1s);

2. G1垃圾回收方式

2.1 G1的GC类型

1)Ygc:仅处理年轻代region
2)MixedGc:包含所有年轻代以及部分老年代Region。
3)FullGc:全堆扫描,每个Region

2.2 G1的gc原则

G1会在无法分配对象或者巨型对象无法获得连续分区来分配空间时,优先尝试扩展堆空间来获得更多的可用分区。
原则上G1会计算执行GC的时间,并且极力减少花在GC上的时间(包括ygc,mixgc),如果可能,会通过不断扩展堆空间来满足对象分配、转移的需要。

2.3 youngGC(年轻代垃圾回收)

触发:分配一般对象(非巨型对象)时,当所有eden的region使用达到最大阀值并且无法申请足够内存时。
younggc会回收所有Eden以及Survivor区,并且将存活对象复制到Old区以及另一部分的Survivor区。到Old区的标准就是在PLAB中得到的计算结果。因为YoungGC会进行根扫描,所以会stop the world。

2.4 MixGC(混合垃圾回收)

触发:一次YoungGc之后,老年代占据堆内存的百占比超过InitiatingHeapOccupancyPercent(默认45%)时,超过这个值就会触发mixedGC。
混合回收都是基于复制算法进行的,把要回收的Region区存活的对象放入其他Region,然后这个Region全部清理掉,这样就会不断空出来新的Region;
有一个参数-XX:G1HeapWastePercent,默认值5%,即空出来的区域大于整个堆的5%,就会立即停止混合回收了。如正常默认回收次数是8次,但是可能到了4次,空闲Region大于整个堆的5%,就不会再进行后续回收了。

2.5 FullGc(全局垃圾回收)

G1在对象复制/转移失败或者没法分配足够内存(比如巨型对象没有足够的连续分区分配)时,会触发FullGC。开始版本FullGC使用的是stop the world的单线程的Serial Old模式。
JDK10以后,Full GC已经是并行运行,在很多场景下,其表现还略优于 Parallel GC 的并行 Full GC 实现。但是仍然要避免fgc。

3. 最佳实践指导

3.1 不要设置年轻代的大小

通过 -Xmn 显式地指定了年轻代的大小, 会干扰到 G1收集器的默认行为:
(1)G1在垃圾收集时将不再关心暂停时间指标. 所以从本质上说,设置年轻代的大小将禁用暂停时间目标;
(2)G1在必要时也不能够增加或者缩小年轻代的空间. 因为大小是固定的,所以对更改大小无能为力;

3.2 设置 XX:MaxGCPauseMillis=<N>

其值不应该使用平均响应时间,应该考虑使用目标时间的90%或者更小作为响应时间指标. 即90%的用户(客户端)请求响应时间不会超过预设的目标值;

3.3 转移失败

survivors 或 promoted objects 进行GC时如果JVM的heap区不足就会发生提升失败(promotion failure). 堆内存不能继续扩充,因为已经达到最大值了。当使用 -XX:+PrintGCDetails 时将会在GC日志中显示 to-space overflow (to-空间溢出)。该操作很昂贵,原因如下:
1)GC仍继续所以空间必须被释放. 
2)拷贝失败的对象必须被放到正确的位置(tenured in place). 
3)CSet指向区域中的任何 RSets 更新都必须重新生成(regenerated). 

避免转移失败的方法:
1)增加保留内存大小, 其默认值是 10;G1保留内存大小,非必须不会使用保留内存;即增大-XX:G1ReservePercent=n
2)更早启动标记周期(marking cycle).即InitiatingHeapOccupancyPercent设置的小一点??
3)增加标记线程(marking threads)的数量. 合理设置-XX:ConcGCThrea

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

程序猿20

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值