记一次G1垃圾回收线上调优的实践

背景

有个项目最近上线了,为了避免后面访问量突增引发不可预知的问题,按照惯例需要进行压测。我选取了几个请求比较频繁的接口进混合压测,发现了一个性能瓶颈,是垃圾回收配置不合理导致的。

我使用的是G1垃圾回收策略。

正文

我压测的步骤是慢慢增加并发,最终看接口的响应时间和TPS等指标,我发现接口并发从200加到250(每个接口的并发,总的并发量是 200*接口数量),TPS并没有明显的提升,TPS一直都是700左右,如下图:

在这里插入图片描述

这说明遇到了瓶颈导致,于是我通过监控开始排查系统的瓶颈究竟在哪。排查了一圈,找到了一个可疑的点,我发现在压测期间,服务进行了600多次的GC,总的GC时间到达了2~5秒,如下图所示:

在这里插入图片描述
在这里插入图片描述

我们知道GC的时候会发生stop the world,所以GC的时间过长肯定会影响接口的响应速度,进而影响接口的TPS。

我继续分析,先看看这些GC是young gc还是full gc,根据下面两个图,可以看到在压测期间,老年代都没有满,而年轻代(eden)则是频繁的爆满释放,那基本可以排除full gc了。

在这里插入图片描述

在这里插入图片描述

为了进一步验证我的猜想,我在服务的启动参数增加如下的选项打印gc日志

-XX:+PrintGC -XX:+PrintGCDetails -XX:+PrintGCTimeStamps -Xloggc:/opt/gc/gc.log

然后进一步分析确认了以上猜想,

在这里插入图片描述

确定了问题点,下面就开始分析问题的原因并思考解决问题的办法。

G1垃圾回收其实是比较复杂的,我这里不打算展开细节,这里只提一个点就是,当Eden区的空间占满之后,会触发Young GC。从上面的图可以看出,我的Eden区大小只有 256 mb,这个值确实有点小,因为的总的堆内存是4G.这个数据让我很困惑,因为我配置G1参数的时候,明明是这样配置的:

-XX:G1NewSizePercent=20 -XX:G1MaxNewSizePercent=30

这两个参数分别是,新生代最小值,默认值5%和新生代最大值,默认值60%。这个比例是相对于总的堆大小的,我的堆大小配置的是:

-Xmx4g -Xms4g

按照这个比例,新生代的大小应该是1G左右啊。似乎我的配置没有生效啊。

于是,我再一次检查整个G1的配置,这次看到了一个可疑的点:

-Xmn256m

这是一个JVM的配置参数,表示把年轻代配置成多大空间,很明显这个配置覆盖了我后面的G1对于新生代的配置。

于是我删除这个配置,重启,然后重新压测。发现GC次数下降了5倍以上,GC时间也下降到了1s以下。看下面这个对比图,效果很明显。

在这里插入图片描述

在这里插入图片描述

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值