高并发场景下JVM调优实践之路

针对视频APP核心接口响应慢的问题,通过监控发现频繁的Full GC和Young GC是主要原因。本文详细记录了从问题定位、优化目标设定、现有问题分析到优化方案的实施,包括选择ParNew + CMS收集器,调整MetaspaceSize和MaxMetaspaceSize,以及通过设置CMSInitiatingOccupancyFraction来减少Full GC的停顿。经过优化,接口P99响应时间显著降低,Full GC次数大幅减少,达到了预期的优化效果。
摘要由CSDN通过智能技术生成

一、背景

2021年2月,收到反馈,视频APP某核心接口高峰期响应慢,影响用户体验。

通过监控发现,接口响应慢主要是P99耗时高引起的,怀疑与该服务的GC有关,该服务典型的一个实例GC表现如下图:

可以看出,在观察周期里:

  • 平均每10分钟Young GC次数66次,峰值为470次;

  • 平均每10分钟Full GC次数0.25次,峰值5次;

可见Full GC非常频繁,Young GC在特定的时段也比较频繁,存在较大的优化空间。由于对GC停顿的优化是降低接口的P99时延一个有效的手段,所以决定对该核心服务进行JVM调优。

二、优化目标

  • 接口P99时延降低30%

  • 减少Young GC和Full GC次数、停顿时长、单次停顿时长

由于GC的行为与并发有关,例如当并发比较高时,不管如何调优,Young GC总会很频繁,总会有不该晋升的对象晋升触发Full GC,因此优化的目标根据负载分别制定:

目标1:高负载(单机1000 QPS以上)

  • Young GC次数减少20%-30% ,Young GC累积耗时不恶化;

  • Full GC次数减少50%以上,单次、累积Full GC耗时减少50%以上,服务发布不触发Full GC。

目标2:中负载(单机500-600)

  • Young GC次数减少20%-30% ,Young GC累积耗时减少20%;

  • Full GC次数不高于4次/天,服务发布不触发Full GC。

目标3:低负载(单机200 QPS以下)

  • Young GC次数减少20%-30% ,Young GC累积耗时减少20%;

  • Full GC次数不高于1次/天,服务发布不触发Full GC。

三、当前存在的问题

当前服务的JVM配置参数如下:

-Xms4096M -Xmx4096M -Xmn1024M-XX:PermSize=512M-XX:MaxPermSize=512M

单纯从参数上分析,存在以下问题:

未显示指定收集器 

JDK 8默认搜集器为ParrallelGC,即Young区采用Parallel Scavenge,老年代采用Parallel Old进行收集,这套配置的特点是吞吐量优先,一般适用于后台任务型服务器。

比如批量订单处理、科学计算等对吞吐量敏感,对时延不敏感的场景,当前服务是视频与用户交互的门户,对时延非常敏感,因此不适合使用默认收集器ParrallelGC,应选择更合适的收集器。

Young区配比不合理

当前服务主要提供API,这类服务的特点是常驻对象会比较少,绝大多数对象的生命周期都比较短,经过一次或两次Young GC就会消亡。

再看下当前JVM配置

整个堆为4G,Young区总共1G,默认-XX:SurvivorRatio=8,即有效大小为0.9G,老年代常驻对象大小约400M。

这就意味着,当服务负载较高,请求并发较大时,Young区中Eden + S0区域会迅速填满,进而Young GC会比较频繁。

另外会引起本应被Young GC回收的对象过早晋升,增加Full GC的频率,同时单次收集的区域也会增大,由于Old区使用的是ParralellOld,无法与用户线程并发执行,导致服务长时间停顿,可用性下降, P99响应时间上升。

未设置

-XX:MetaspaceSize和-XX:MaxMetaspaceSize

Perm区在jdk 1.8已经过时,被Meta区取代,因此-XX:PermSize=512M -XX:MaxPermSize=512M配置会被忽略,真正控制Meta区GC的参数为-XX:MetaspaceSize:Metaspace初始大小,64位机器默认为21M左右 -XX:MaxMetaspaceSize:Metaspace的最大值,64位机器默认为18446744073709551615Byte,可以理解为无上限 -XX:MaxMetaspaceExpansion:增大触发metaspace GC阈值的最大要
一、什么是JVM  JVMJava Virtual Machine(Java虚拟机)的缩写,JVM是一种用于计算设备的规范,它是一个虚构出来的计算机,是通过在实际的计算机上仿真模拟各种计算机功能来实现的。Java虚拟机包括一套字节码指令集、一组寄存器、一个栈、一个垃圾回收堆和一个存储方法域。 JVM屏蔽了与具体操作系统平台相关的信息,使Java程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。JVM在执行字节码时,实际上最终还是把字节码解释成具体平台上的机器指令执行。  Java语言的一个非常重要的特点就是与平台的无关性。而使用Java虚拟机是实现这一特点的关键。一般的高级语言如果要在不同的平台上运行,至少需要编译成不同的目标代码。而引入Java语言虚拟机后,Java语言在不同平台上运行时不需要重新编译。Java语言使用Java虚拟机屏蔽了与具体平台相关的信息,使得Java语言编译程序只需生成在Java虚拟机上运行的目标代码(字节码),就可以在多种平台上不加修改地运行。Java虚拟机在执行字节码时,把字节码解释成具体平台上的机器指令执行。这就是Java的能够“一次编译,到处运行”的原因。二、JVM的组成我们先把JVM这个虚拟机画出来,如下图所示:从这张图中我们可以看出,JVM是运行在操作系统之上的,它与硬件没有直接的交互,我们再来看JVM由哪些部分组成,如下图所示:
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值