当前位置:首页 > 科技  > 软件

解决GC毛刺问题——转转搜索推荐服务JDK17升级实践

来源: 责编: 时间:2023-09-28 10:07:18 177观看
导读1 升级背景随着转转业务规模的不断增长,我们的搜索推荐服务正在面临严峻的垃圾回收(Garbage Colletion, GC)带来的服务接口耗时毛刺问题。我们当前所使用的JDK1.8版本中的CMS和G1收集器,在应对请求高峰时均不理想,经常出现

1 升级背景

随着转转业务规模的不断增长,我们的搜索推荐服务正在面临严峻的垃圾回收(Garbage Colletion, GC)带来的服务接口耗时毛刺问题。ug728资讯网——每日最新资讯28at.com

我们当前所使用的JDK1.8版本中的CMS和G1收集器,在应对请求高峰时均不理想,经常出现的停顿问题直接影响了服务的可用性及用户体验。ug728资讯网——每日最新资讯28at.com

我们面临的核心挑战是:ug728资讯网——每日最新资讯28at.com

  • 服务请求流量激增时,GC次数频繁是我们的一大痛点,每分钟有可能达到十几次以上。另一方面,单次GC停顿时间也较长,可高达数十毫秒。这不但降低了服务的可用性,也限制了服务的吞吐量,对于我们的在线服务是难以接受的。
  • 同时GC参数的调优工作遇到瓶颈,尽管还可以通过减少新对象创建速率等方式继续优化,但整体投入产出比偏低。

为此,我们计划通过升级JDK版本来实现GC问题的改善。JDK新版本带来了如ZGC、Shenandoah等新一代GC算法,它们能够提供极低的GC停顿时间,有望解决我们的在线服务目前的GC毛刺问题。ug728资讯网——每日最新资讯28at.com

我们的升级目标是利用新版本JDK中的新GC算法,将搜索推荐服务的GC停顿时间降低90%以上,保证高流量服务的可用性和吞吐量,进一步提升用户体验。ug728资讯网——每日最新资讯28at.com

2 JDK17简介

我们选择将JDK版本升级到JDK17,主要原因有:ug728资讯网——每日最新资讯28at.com

  • 一方面,JDK17是目前最新的长期支持(Long Term Support,LTS)版本,相比其他版本,它能提供更稳定和持久的支持,同时也有大量企业应用了JDK17,有丰富成熟的使用经验。可以预见JDK17在未来一段时间也将会是主流版本,能得到更好的社区支持。
  • 另一方面,JDK17作为新一代版本,与旧版JDK8相比,既能与现有代码上保持兼容性,又在语法和GC算法等多个方面做出了重要改进和优化。如JDK17包含了可用于生产环境的ZGC,且它的性能在历代版本迭代下,得到大幅增强。

2.1 新语法简介

具体来看,此次JDK 17的升级在语法上带来了以下几个值得注意的新特性:ug728资讯网——每日最新资讯28at.com

类型推断ug728资讯网——每日最新资讯28at.com

从JDK10版本开始,引入了局部变量类型推断(Local Variable Type Inference)功能,它可以让我们在声明局部变量时省略变量类型,而由编译器根据变量初始化的值自动推断出类型。    ug728资讯网——每日最新资讯28at.com

// 传统变量声明方法String str = "hello";// 使用类型推断的变量声明方法var str = "hello";

Stream API的增强ug728资讯网——每日最新资讯28at.com

JDK新版本对Stream API进行了一些增强,主要有:ug728资讯网——每日最新资讯28at.com

takeWhile和dropWhile会对流中每个元素逐一校验,遇到第一个不符合条件的元素终止,takeWhile返回终止位置前面的所有元素,而dropWhile则返回包含终止位置后面的所有元素。它们功能虽然与filter类似,区别是前者并非对整个流进行校验,可以提升过滤效率,但需要注意流内元素的顺序。ug728资讯网——每日最新资讯28at.com

var list = List.of(1,2,3,4,5,6);// 输出:1,2;list.stream().takeWhile(n -> n < 3).forEach(System.out::println); // 输出:3,4,5,6list.stream().dropWhile(n -> n < 3).forEach(System.out::println);

iterate可以生成一个无限的流,它在JDK9之前需要limit()等操作来配合终止,否则将无限递归下去。在JDK9中iterate新增了一个重载方法,现在支持使用条件来终止,它在语法上更简洁,也提供了更多的灵活性。ug728资讯网——每日最新资讯28at.com

// 输出:1,2,4,8,...,512,1024Stream.iterate(1, n -> n <= 1024, n -> n * 2).forEach(System.out::println);

集合API新增方法ug728资讯网——每日最新资讯28at.com

操作集合将更加方便,如可以更加简洁的创建List和Map,但需要注意这种方式创建的集合均是不可变的。ug728资讯网——每日最新资讯28at.com

var list = List.of(1, 2, 3, 4, 5);var map1 = Map.of("a", 1, "b", 2);var map2 = Map.ofEntries(Map.entry("a", 1), Map.entry("b", 2));

同时新增了多种Collector方法,如可以通过groupingBy新增的重载方法实现多级分组,假设Product类有Cate、Brand、Model成员,则可以做如下多层分组收集:ug728资讯网——每日最新资讯28at.com

// 按Cate、Brand分组,收集Model列表List<Product> products = ...;Map<Cate, Map<Brand, List<Model>>> result = products.stream()  .collect(Collectors.groupingBy(Product::getCate,          Collectors.groupingBy(Product::getBrand,          Collectors.mapping(Product::getModel, Collectors.toList()))));

Swtich新语法ug728资讯网——每日最新资讯28at.com

JDK12开始,switch语句增加了新的语法形式,允许使用更灵活的表达式匹配,并可以返回值,提升了代码的简洁性。ug728资讯网——每日最新资讯28at.com

int month = ...;String days = switch(month) {  case 1, 3, 5, 7, 8, 10, 12 -> "31 days";  case 4, 6, 9, 11 -> "30 days";  case 2 -> "28 or 29 days";}

文本块ug728资讯网——每日最新资讯28at.com

JDK13开始提供了一种新的字符串格式,用户可以选择用三个双引号(""")作为字符串开头及结尾,直接编写多行文本,它为JSON、SQL等格式的字符串编写提升了简洁性和便利性。ug728资讯网——每日最新资讯28at.com

String textBlock = """                   This is a text block                   spanning multiple lines.                   """;

Record类型ug728资讯网——每日最新资讯28at.com

JDK14中新增的Record提供了更简洁的语法来生成只用于数据存储的类,并自动生成访问方法、equals和hashCode比较方法以及toString方法,它可以在类内部或方法内部生成。它相比class类更轻量简洁,相比Pair、Triple等组合类Record的语义上更加明确、代码可读性更强。ug728资讯网——每日最新资讯28at.com

void someMethod() {    record Product(long id, String category);    Product product = new Product(101L, "phone");    long productId = product.getId();    String productCategory = product.getCategory();}

模式匹配新语法

JDK14版本引入了模式匹配新语法,避免了冗余的类型转换语句。ug728资讯网——每日最新资讯28at.com

Object obj = ...;if (obj instanceof String s) {  System.out.println("String: " + s.length());} else if (obj instanceof Integer i) {  System.out.println("Integer: " + i);} else {  System.out.println("Unknown object");}

JDK17版本后,新的模式匹配方式也可以在Switch语句中使用了。ug728资讯网——每日最新资讯28at.com

Object obj = ...;switch(obj) {    case String s -> System.out.println("String: " + s.length());    case Integer i -> System.out.println("Integer: " + i);    default -> System.out.println("Unknown object");}

密封类

密封类(Sealed Class)是JDK15引入的新特性,当使用sealed关键字修饰一个抽象类时,表示这个抽象类只允许指定的类来继承实现。ug728资讯网——每日最新资讯28at.com

如下ProductField类只允许Cate、Brand、Model类继承,这种特性避免了意料外的类型扩展,提升了类型安全性。ug728资讯网——每日最新资讯28at.com

sealed abstract class ProductField permits Cate, Brand, Model {   //...}

此外,JDK新版本还有向量API等新特性和诸多改进等待我们探索发现。ug728资讯网——每日最新资讯28at.com

2.2 新GC算法简介

ZGC介绍ug728资讯网——每日最新资讯28at.com

ZGC在JDK11作为实验性的GC算法被引入时,最初的设计目标是实现10毫秒以内的最大停顿时间。在过去一段时间里,ZGC经过JDK版本的数次迭代,在JDK15中被宣布为可用于生产,目前据官方介绍已经可以实现亚毫秒级的最大停顿时间,且停顿时间不随堆内存、存活对象集合或GCRoot集合大小的增加而增加,它可以处理从8MB到16TB的大范围堆内存。ug728资讯网——每日最新资讯28at.com

在官方介绍里,ZGC是并发的、基于区域的(Region-based)、压缩的(Compacting)、NUMA感知(NUMA-aware)的垃圾回收器。它主要使用了染色指针(Colored Pointor)和读屏障(Load Barriers)技术,并在新一代的JDK21版本中实现了分代回收,它的主要工作是在用户线程工作执行时完成的,这大大降低了GC对应用响应时间的影响。ug728资讯网——每日最新资讯28at.com

使用如下JVM启动参数可以快速应用ZGC:ug728资讯网——每日最新资讯28at.com

-XX:+UseZGC

Shenandoah GC介绍ug728资讯网——每日最新资讯28at.com

Shenandoah GC是一种全新的低延迟垃圾收集器,在JDK 8的部分版本可用,从JDK 11版本正式引入,它通过读写屏障和并发标记技术,可以极大缩短GC时的应用程序停顿。ug728资讯网——每日最新资讯28at.com

相比CMS、G1等算法,其停顿时间更短,支持超大内存,非常适合对响应时间敏感类型的服务。由于Shenandoah使用了读写屏障技术,虽然可能导致吞吐量略降,但总体来说是更有效的GC算法之一。ug728资讯网——每日最新资讯28at.com

使用如下参数可以快速应用Shenandoah GC:ug728资讯网——每日最新资讯28at.com

-XX:+UseShenandoahGC

3 升级过程

JDK版本升级无需做太多代码改动,但要平滑过渡到新版本,也需要做充分准备和规划。本节将分享我们升级到JDK17的具体步骤,在此过程中遇到的问题及解决方法,以及对ZGC相关问题的分析。ug728资讯网——每日最新资讯28at.com

3.1 升级步骤

安装JDK17ug728资讯网——每日最新资讯28at.com

我们在本地测试时选择了Eclipse Temurin Build版本,根据官网介绍它是由基于OpenJDK的开源Java SE产生的构建版本,这里根据开发环境的机器配置下载并安装了jdk-17.0.7+7 macos aarch64版本。ug728资讯网——每日最新资讯28at.com

调整IDE配置

在使用IntelliJ Idea开发环境时,可以在文件--项目结构配置中,将SDK选项调整到刚刚安装的JDK版本。ug728资讯网——每日最新资讯28at.com

图片图片ug728资讯网——每日最新资讯28at.com

调整项目配置

由于我们的项目是Maven项目,需要选择POM文件,修改Maven的编译插件的source和target配置到17。ug728资讯网——每日最新资讯28at.com

<properties>  <jdk.version>17</jdk.version></properties>...<plugins>  <plugin>    <groupId>org.apache.maven.plugins</groupId>    <artifactId>maven-compiler-plugin</artifactId>    <configuration>      <source>${jdk.version}</source>      <target>${jdk.version}</target>    </configuration>  </plugin></plugins>

部署测试

本地编译测试通过后,意味着可以到测试环境进行部署和验证了,验证内容包括全场景的功能验证、DIFF验证、压力性能测试等等(由于部署功能是由公司其他系统提供,不展开叙述)。ug728资讯网——每日最新资讯28at.com

升级JDK17后,JVM启动参数需要调整,一些旧参数被废弃,同时增加新的参数,我们用于测试环境部署的参数为:ug728资讯网——每日最新资讯28at.com

-Xms6g -Xmx6g -XX:MetaspaceSize=256m -XX:MaxMetaspaceSize=512m -Xss256k -XX:+UseZGC -XX:ParallelGCThreads=12

生产环境部署及效果数据回收ug728资讯网——每日最新资讯28at.com

升级JDK后,回收线上服务的效果数据至关重要,我们主要关注服务延时表现、GC暂停表现以及内存消耗表现。ug728资讯网——每日最新资讯28at.com

我们选择服务集群的50%节点来部署JDK17,另外50%节点保持JDK8不变作为对照组,分配节点时,保持各组的节点机器配置情况一致,将实验变量控制在仅JDK版本的切换上。ug728资讯网——每日最新资讯28at.com

同时将服务访问的延时信息、GC暂停信息、堆内存使用信息上报到日志收集系统。由于前者的日志规模庞大,为了获取更精确的统计信息,通过上报到大数据平台并使用HiveSql分析,后两者则通过上报Promethues监控平台来实现实时信息收集。ug728资讯网——每日最新资讯28at.com

3.2 遇到问题及解决方法

在实际编译和部署的过程中,还可能会遇到各种各样的问题,下面我们对遇到的问题及解决方法做了一些梳理。ug728资讯网——每日最新资讯28at.com

以下为编译期间遇到的一些问题:ug728资讯网——每日最新资讯28at.com

非法字符引发的异常ug728资讯网——每日最新资讯28at.com

Maven编译期间遇见如下报错:ug728资讯网——每日最新资讯28at.com

[ERROR] Internal error: java.lang.IllegalArgumentException: Malformed /uxxxx encoding. -> [Help 1]

问题原因:这是Maven在加载一些配置文件时遇到了不兼容的编码字符导致的。本地Maven仓库路径下的resolver-status.properties文件中存在格式不正确的unicode编码字符,这些字符在JDK 17的字符串处理方式下无法解析。ug728资讯网——每日最新资讯28at.com

解决方法:使用以下命令,递归删除本地仓库下所有的resolver-status.properties文件:ug728资讯网——每日最新资讯28at.com

find ~/.m2/ -name resolver-status.properties -delete

包不存在引发的异常ug728资讯网——每日最新资讯28at.com

编译器期间提示包不存在:ug728资讯网——每日最新资讯28at.com

import javafx.util.Pair

问题原因:javafx等包在JDK新版本中被默认移除。ug728资讯网——每日最新资讯28at.com

解决方法:可以使用apache.commons提供的Pair类替代,也可以手动引入被移除的依赖,其他被移除的类也可以通过类似的方法解决。ug728资讯网——每日最新资讯28at.com

以下为部署期间遇到的问题:ug728资讯网——每日最新资讯28at.com

JVM参数引发的异常ug728资讯网——每日最新资讯28at.com

启动阶段可能遇到类似如下问题:ug728资讯网——每日最新资讯28at.com

Unrecognized VM option 'UseGCLogFileRotation'Error: Could not create the Java Virtual Machine.Error: A fatal exception has occurred. Program will exit.

问题原因:部分JVM参数在新版本不再兼容,导致不能识别。ug728资讯网——每日最新资讯28at.com

解决方法:从启动参数里将不兼容的参数移除即可,同时寻找替代参数。ug728资讯网——每日最新资讯28at.com

反射访问引发的异常ug728资讯网——每日最新资讯28at.com

如以下日志所示,我们在初始化apollo配置中心组件时遇到了启动异常,从异常描述看是程序反射访问期间引起的。ug728资讯网——每日最新资讯28at.com

java.lang.IllegalArgumentException: Cannot instantiate interface org.springframework.context.ApplicationContextInitializer : com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer        ...        at com.bj58.spat.scf.server.bootstrap.Main.main(Main.java:27) [zzscf.server-2.7.12.jar:?]Caused by: org.springframework.beans.BeanInstantiationException: Failed to instantiate [com.ctrip.framework.apollo.spring.boot.ApolloApplicationContextInitializer]: Constructor threw exception; nested exception is com.ctrip.framework.apollo.exceptions.ApolloConfigException: [ARCH_APOLLO_CLIENT]Unable to load instance for com.ctrip.framework.apollo.spring.config.ConfigPropertySourceFactory!        at org.springframework.beans.BeanUtils.instantiateClass(BeanUtils.java:154) ~[spring-beans-4.3.12.RELEASE.jar:4.3.12.RELEASE]        at org.springframework.boot.SpringApplication.createSpringFactoriesInstances(SpringApplication.java:409) ~[spring-boot-1.5.8.RELEASE.jar:1.5.8.RELEASE]        ... 8 more...Caused by: java.lang.reflect.InaccessibleObjectException: Unable to make protected final java.lang.Class java.lang.ClassLoader.defineClass(java.lang.String,byte[],int,int,java.security.ProtectionDomain) throws java.lang.ClassFormatError accessible: module java.base does not "opens java.lang" to unnamed module @5e265ba4        at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:354) ~[?:?]        at java.lang.reflect.AccessibleObject.checkCanSetAccessible(AccessibleObject.java:297) ~[?:?]        at java.lang.reflect.Method.checkCanSetAccessible(Method.java:199) ~[?:?]        at java.lang.reflect.Method.setAccessible(Method.java:193) ~[?:?]...

问题原因:新版本JDK引入了模块访问控制,跨模块时无法简单的直接通过反射访问了,上述异常是想要通过反射访问Java内部模块而抛出的ug728资讯网——每日最新资讯28at.com

解决方法:对于此类问题,可以通过临时增加如下启动参数解决,也可以查阅依赖包的新版本,了解它们是否已对JDK新版本做出了适配ug728资讯网——每日最新资讯28at.com

--add-opens java.base/java.lang=ALL-UNNAMED

java.base/java.lang是本次异常需要用到的模块参数,在解决此类异常时,需要根据实际要访问的模块名进行调整,以下为我们收集的一些启动参数,可以按需增加启动参数配置。ug728资讯网——每日最新资讯28at.com

--add-opens java.base/java.lang=ALL-UNNAMED --add-opens java.base/java.io=ALL-UNNAMED --add-opens java.base/java.math=ALL-UNNAMED --add-opens java.base/java=ALL-UNNAMED --add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.security=ALL-UNNAMED --add-opens java.base/java.text=ALL-UNNAMED --add-opens java.base/java.time=ALL-UNNAMED --add-opens java.base/java.util=ALL-UNNAMED --add-opens java.base/jdk.internal.access=ALL-UNNAMED --add-opens java.base/jdk.internal.misc=ALL-UNNAMED

注解类型被默认移除引发的异常ug728资讯网——每日最新资讯28at.com

启动过程中,发现抛出了如下空指针异常ug728资讯网——每日最新资讯28at.com

Caused by: java.lang.NullPointerException: Cannot invoke "String.length()" because "s" is null        at java.base/java.URLEncoder.encode(URLEncoder.java:224)        at java.base/java.URLEncoder.encode(URLEncoder.java:196)        at com.bj58.zhuanzhuan.arch.service.manager.sdk.client.CallPermissionService.initUri(CallPermissionService.java:192)        at com.bj58.zhuanzhuan.arch.service.manager.sdk.client.CallPermissionService.<init>(CallPermissionService.java:72)        at com.bj58.spat.scf.server.filter.BlackKeyRequestFilter.afterPropertiesSet(BlackKeyRequestFilter.java:120)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.invokeInitMethods(AbstractAutowireCapableBeanFactory.java:1687)        at org.springframework.beans.factory.support.AbstractAutowireCapableBeanFactory.initializeBean(AbstractAutowireCapableBeanFactory.java:1624)        ... 15 more

问题原因:分析调用链路后发现,问题发生在一个上下文类,它的init方法是通过@PostConstruct注解触发执行的,该注解在JDK新版本中被默认移除了,导致init方法未能执行ug728资讯网——每日最新资讯28at.com

解决方法:短期可以通过手动引入以下依赖方式解决,长期同样可以查阅依赖包维护方的更新日志,或与维护方进行沟通,将依赖更新到已适配版本。ug728资讯网——每日最新资讯28at.com

<dependency>    <groupId>javax.annotation</groupId>    <artifactId>javax.annotation-api</artifactId>    <version>1.3.2</version></dependency>

此外我们在发布到生产环境后,还遇到了以下问题:ug728资讯网——每日最新资讯28at.com

ZGC的虚拟内存申请的疑问ug728资讯网——每日最新资讯28at.com

我们的服务升级JDK并在实际生产环境部署后,同物理节点的其他服务曾出现了一次短暂的资源耗尽异常,当时我们怀疑导致问题原因之一是ZGC申请了过多的虚拟内存。ug728资讯网——每日最新资讯28at.com

针对ZGC申请过多虚拟内存问题,我们经过排查发现,这并不是JDK17存在的问题,而是由ZGC自身的实现机制所导致的。ZGC通过染色指针和多重映射技术来实现高吞吐低延迟的GC。ug728资讯网——每日最新资讯28at.com

为了实现染色指针,ZGC需要使用地址高位额外的bit来记录对象状态,所以需要的虚拟内存空间远高于实际堆大小。此外,以目前JDK17版本,它还会为不同状态的对象分配独立的虚拟内存,以实现并发回收,具体来说需要为remapped、marked0、marked1三种状态申请三份独立虚拟内存空间。ug728资讯网——每日最新资讯28at.com

以4TB堆为例,ZGC需要4bit用于染色,所以需要4TB * 2^4 = 128TB虚拟内存。它还会为每种染色状态各自申请128TB空间。所以4TB堆最终会申请128TB * 3约等于384TB的虚拟内存。ug728资讯网——每日最新资讯28at.com

本例中我们的服务实际使用6GB堆,通过与内存工具Native Memory Tracking输出结果比对,发现跟公式计算结果一致,ZGC申请了约300GB的虚拟内存,符合其技术实现的需要。ug728资讯网——每日最新资讯28at.com

所以结论是ZGC申请虚拟内存并非JDK问题,是其特有的技术实现方式导致。ug728资讯网——每日最新资讯28at.com

4 升级效果

以下是我们在转转的通用推荐服务升级过程中,持续对比三个全天收集到的效果数据,我们设立50%节点升级到JDK17作为实验组,另50%节点不升级作为对照组。ug728资讯网——每日最新资讯28at.com

4.1 整体耗时对比

首先看下服务的整体耗时数据,如下图所示,可以看到该服务升级JDK17后tp999及tp9999时间有显著降低。ug728资讯网——每日最新资讯28at.com

图片图片ug728资讯网——每日最新资讯28at.com

整体耗时对比

通过新版本GC算法的引入,服务处理请求的尾部延时情况得到了改善,响应时间的毛刺问题明显减轻。ug728资讯网——每日最新资讯28at.com

下表为详细数据:ug728资讯网——每日最新资讯28at.com

指标/版本
ug728资讯网——每日最新资讯28at.com

JDK8
ug728资讯网——每日最新资讯28at.com

JDK17
ug728资讯网——每日最新资讯28at.com

降幅
ug728资讯网——每日最新资讯28at.com

AVG耗时
ug728资讯网——每日最新资讯28at.com

22ms
ug728资讯网——每日最新资讯28at.com

22msug728资讯网——每日最新资讯28at.com

持平
ug728资讯网——每日最新资讯28at.com

TP50耗时
ug728资讯网——每日最新资讯28at.com

11ms
ug728资讯网——每日最新资讯28at.com

11ms
ug728资讯网——每日最新资讯28at.com

持平
ug728资讯网——每日最新资讯28at.com

TP90耗时
ug728资讯网——每日最新资讯28at.com

57ms
ug728资讯网——每日最新资讯28at.com

57ms
ug728资讯网——每日最新资讯28at.com

持平
ug728资讯网——每日最新资讯28at.com

TP99耗时
ug728资讯网——每日最新资讯28at.com

149ms
ug728资讯网——每日最新资讯28at.com

148ms
ug728资讯网——每日最新资讯28at.com

0.67%
ug728资讯网——每日最新资讯28at.com

TP999耗时
ug728资讯网——每日最新资讯28at.com

249ms
ug728资讯网——每日最新资讯28at.com

242ms
ug728资讯网——每日最新资讯28at.com

2.81%
ug728资讯网——每日最新资讯28at.com

TP9999耗时
ug728资讯网——每日最新资讯28at.com

601ms
ug728资讯网——每日最新资讯28at.com

458ms
ug728资讯网——每日最新资讯28at.com

23.78%
ug728资讯网——每日最新资讯28at.com

4.2 分节点耗时对比

在分节点的指标对比上,我们发现应用JDK17的节点在tp999和tp9999这两个高延迟分位数指标上的表现更加平稳。ug728资讯网——每日最新资讯28at.com

如下图所示,相比保持JDK8的对照组节点,升级到JDK17的实验组节点,其tp999和tp9999指标的变化曲线更加平坦。ug728资讯网——每日最新资讯28at.com

节点TP999耗时对比节点TP999耗时对比ug728资讯网——每日最新资讯28at.com


ug728资讯网——每日最新资讯28at.com

节点TP9999耗时对比节点TP9999耗时对比ug728资讯网——每日最新资讯28at.com


ug728资讯网——每日最新资讯28at.com

4.3 GC停顿时长对比

对于GC数据,我们收集了服务晚间4小时JDK8和JDK17版本的GC停顿数据。JDK8统计了其Young GC的暂停时间,而JDK 17统计了ZGC Pause时间。ug728资讯网——每日最新资讯28at.com

从下表可以明显看出,使用JDK17的ZGC算法后,GC停顿时长大幅减少。JDK8下YGC每分钟平均暂停时间为221ms,而JDK 17下的ZGC只有0.37ms,降幅高达99.83%。ug728资讯网——每日最新资讯28at.com

指标/版本
ug728资讯网——每日最新资讯28at.com

JDK8
ug728资讯网——每日最新资讯28at.com

JDK17
ug728资讯网——每日最新资讯28at.com

降幅
ug728资讯网——每日最新资讯28at.com

统计口径
ug728资讯网——每日最新资讯28at.com

YGC时间
ug728资讯网——每日最新资讯28at.com

ZGC Pause时间
ug728资讯网——每日最新资讯28at.com

-
ug728资讯网——每日最新资讯28at.com

总时长
ug728资讯网——每日最新资讯28at.com

106250ms
ug728资讯网——每日最新资讯28at.com

221ms
ug728资讯网——每日最新资讯28at.com

99.67%
ug728资讯网——每日最新资讯28at.com

每分钟平均时长
ug728资讯网——每日最新资讯28at.com

355ms
ug728资讯网——每日最新资讯28at.com

0.37ms
ug728资讯网——每日最新资讯28at.com

99.83%
ug728资讯网——每日最新资讯28at.com

停顿时间的降低不仅提高了服务的可用性,也使系统吞吐量获得大幅提升。ug728资讯网——每日最新资讯28at.com

4.4 堆空间占用对比

从下表统计数据可以看出,使用JDK 17后,相同堆空间配置下,实际堆内存占用有所降低,堆空间的利用效率得到提高。ug728资讯网——每日最新资讯28at.com

在同为6G堆大小情况下,JDK 8堆占用平均为2.92G,占比48.7%;而JDK 17堆占用平均减少至2.42G,占比降至40.3%。堆内存占用比降低了17.2%。ug728资讯网——每日最新资讯28at.com

这表明在不改变堆区设置的前提下,JDK 17可以提高堆空间的利用效率,降低内存占用,为系统留出更多可用内存空间,从而提高系统稳定性。ug728资讯网——每日最新资讯28at.com

指标/版本
ug728资讯网——每日最新资讯28at.com

JDK8
ug728资讯网——每日最新资讯28at.com

JDK17
ug728资讯网——每日最新资讯28at.com

降幅
ug728资讯网——每日最新资讯28at.com

堆空间申请
ug728资讯网——每日最新资讯28at.com

6G
ug728资讯网——每日最新资讯28at.com

6G
ug728资讯网——每日最新资讯28at.com

-
ug728资讯网——每日最新资讯28at.com

每分钟平均堆占用
ug728资讯网——每日最新资讯28at.com

2.922G
ug728资讯网——每日最新资讯28at.com

2.419G
ug728资讯网——每日最新资讯28at.com

17.20%
ug728资讯网——每日最新资讯28at.com

每分钟平均堆占用比
ug728资讯网——每日最新资讯28at.com

48.70%
ug728资讯网——每日最新资讯28at.com

40.32%
ug728资讯网——每日最新资讯28at.com

17.20%
ug728资讯网——每日最新资讯28at.com

另外ZGC提供了-XX:SoftMaxHeapSize参数,用于弹性调节堆空间的最大值,当堆大小未超出设定值时可以释放更多空闲内存。ug728资讯网——每日最新资讯28at.com

5 总结

截止至发文,服务已成功部署应用JDK17并平稳运行一月有余。通过本次升级,我们获得了显著的GC停顿时间和内存占用率的改善效果,有效解决了服务GC问题,进而降低了服务高分位延迟指标,充分验证了JDK17新版本GC算法的优势。ug728资讯网——每日最新资讯28at.com

同时,我们也积累了语法改进、升级中跨部门协调、问题排查等方面的宝贵经验。升级过程中遇到了服务稳定性问题,也让我们意识到需要对新特性有更深入的理解,平稳地应用到生产环境。ug728资讯网——每日最新资讯28at.com

后续我们将继续关注JDK新版本的特性改进,并逐步将搜索推荐核心服务完全升级到JDK17新版本,以获得更好的开发体验和服务运行效果。ug728资讯网——每日最新资讯28at.com

关于作者ug728资讯网——每日最新资讯28at.com

曾祥瑞,转转搜索推荐研发工程师ug728资讯网——每日最新资讯28at.com

锐意进取,勇于试验,与时俱进。ug728资讯网——每日最新资讯28at.com

本文链接:http://www.28at.com/showinfo-26-11831-0.html解决GC毛刺问题——转转搜索推荐服务JDK17升级实践

声明:本网页内容旨在传播知识,若有侵权等问题请及时与本网联系,我们将在第一时间删除处理。邮件:2376512515@qq.com

上一篇: 微软在 GitHub 上线开发工具包,助力开发者使用 Rust 语言编写 Windows 驱动

下一篇: 18个不可不知的Spring Cloud微服务架构知识点

标签:
  • 热门焦点
Top