Spring Boot 3.3.0 新特性| 使用 CDS 优化启动时间

JAVA架构日记

共 11161字,需浏览 23分钟

 ·

2024-05-31 10:20

一、CDS 是什么?

类数据共享 (CDS) 是一项 JVM 功能,可帮助减少 Java 应用程序的启动时间和内存占用。从 JDK 12 开始,默认的 CDS 归档文件与 Oracle JDK 二进制文件一起预打包。笔者测试使用的 OpenJDK 64-Bit Server VM Zulu21.34+19-CA (build 21.0.3+9-LTS, mixed mode, sharing)它也是支持 CDS 的。

二、如何使用

2.1 训练

要使用它,您应该首先以分解形式对应用程序执行训练运行:

$ java -Djarmode=tools -jar my-app.jar extract --destination application

$
 cd application

$
 java -XX:ArchiveClassesAtExit=application.jsa -Dspring.context.exit=onRefresh -jar my-app.jar

这将创建一个  application 目录并生成 application.jsa,只要应用程序未更新,就可以重复使用。

2.2 使用

要使用缓存,您需要在启动应用程序时添加一个额外的 -XX:SharedArchiveFile 参数:

$ java -XX:SharedArchiveFile=application.jsa -jar my-app.jar

三、效果

为了测试 CDS,笔者使用 Spring Boot initializr 生成了一个 demo 项目。下面是 CDS 训练后的 application 目录的结构:

$ tree application
application
|-- application.jsa
|-- demo-0.0.1-SNAPSHOT.jar
`-- lib
    |-- jackson-annotations-2.17.1.jar
    |-- jackson-core-2.17.1.jar
    |-- jackson-databind-2.17.1.jar
    |-- jackson-datatype-jdk8-2.17.1.jar
    |-- jackson-datatype-jsr310-2.17.1.jar
    |-- jackson-module-parameter-names-2.17.1.jar
    |-- jakarta.annotation-api-2.1.1.jar
    |-- jul-to-slf4j-2.0.13.jar
    |-- log4j-api-2.23.1.jar
    |-- log4j-to-slf4j-2.23.1.jar
    |-- logback-classic-1.5.6.jar
    |-- logback-core-1.5.6.jar
    |-- micrometer-commons-1.13.0.jar
    |-- micrometer-observation-1.13.0.jar
    |-- slf4j-api-2.0.13.jar
    |-- snakeyaml-2.2.jar
    |-- spring-aop-6.1.8.jar
    |-- spring-beans-6.1.8.jar
    |-- spring-boot-3.3.0.jar
    |-- spring-boot-autoconfigure-3.3.0.jar
    |-- spring-boot-jarmode-tools-3.3.0.jar
    |-- spring-context-6.1.8.jar
    |-- spring-core-6.1.8.jar
    |-- spring-expression-6.1.8.jar
    |-- spring-jcl-6.1.8.jar
    |-- spring-web-6.1.8.jar
    |-- spring-webmvc-6.1.8.jar
    |-- tomcat-embed-core-10.1.24.jar
    |-- tomcat-embed-el-10.1.24.jar
    `-- tomcat-embed-websocket-10.1.24.jar

1 directory, 32 files

3.1 直接运行 demo-0.0.1-SNAPSHOT.jar

$ java -jar demo-0.0.1-SNAPSHOT.jar
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '
_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

2024-05-31T08:53:39.964+08:00  INFO 14832 --- [demo] [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT using Java 21.0.3 with PID 14832 (D:\test\demo\target\demo-0.0.1-SNAPSHOT.jar started by L.cm in D:\test\demo\target)
2024-05-31T08:53:39.967+08:00  INFO 14832 --- [demo] [           main] com.example.demo.DemoApplication         : No active profile set, falling back to 1 default profile: "default"
2024-05-31T08:53:40.893+08:00  INFO 14832 --- [demo] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8888 (http)
2024-05-31T08:53:40.908+08:00  INFO 14832 --- [demo] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-05-31T08:53:40.908+08:00  INFO 14832 --- [demo] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.24]
2024-05-31T08:53:40.948+08:00  INFO 14832 --- [demo] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-05-31T08:53:40.949+08:00  INFO 14832 --- [demo] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 921 ms
2024-05-31T08:53:41.257+08:00  INFO 14832 --- [demo] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8888 (http) with context path '
/'
2024-05-31T08:53:41.274+08:00  INFO 14832 --- [demo] [           main] com.example.demo.DemoApplication         : Started DemoApplication in 1.702 seconds (process running for 2.143)

我们可以在日志 Started DemoApplication in 1.702 seconds 看到启动耗时为 1.702 秒。

3.2 使用 CDS 运行

需要先 cd 到训练的 application 目录。

$ java -XX:SharedArchiveFile=application.jsa -jar demo-0.0.1-SNAPSHOT.jar
  .   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '
_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/

 :: Spring Boot ::                (v3.3.0)

2024-05-31T08:53:15.828+08:00  INFO 21444 --- [demo] [           main] com.example.demo.DemoApplication         : Starting DemoApplication v0.0.1-SNAPSHOT using Java 21.0.3 with PID 21444 (D:\test\demo\target\application\demo-0.0.1-SNAPSHOT.jar started by L.cm in D:\test\demo\target\application)
2024-05-31T08:53:15.830+08:00  INFO 21444 --- [demo] [           main] com.example.demo.DemoApplication         : No active profile set, falling back to 1 default profile: "default"
2024-05-31T08:53:16.244+08:00  INFO 21444 --- [demo] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat initialized with port 8888 (http)
2024-05-31T08:53:16.249+08:00  INFO 21444 --- [demo] [           main] o.apache.catalina.core.StandardService   : Starting service [Tomcat]
2024-05-31T08:53:16.249+08:00  INFO 21444 --- [demo] [           main] o.apache.catalina.core.StandardEngine    : Starting Servlet engine: [Apache Tomcat/10.1.24]
2024-05-31T08:53:16.272+08:00  INFO 21444 --- [demo] [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2024-05-31T08:53:16.273+08:00  INFO 21444 --- [demo] [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 419 ms
2024-05-31T08:53:16.425+08:00  INFO 21444 --- [demo] [           main] o.s.b.w.embedded.tomcat.TomcatWebServer  : Tomcat started on port 8888 (http) with context path '
/'
2024-05-31T08:53:16.431+08:00  INFO 21444 --- [demo] [           main] com.example.demo.DemoApplication         : Started DemoApplication in 0.722 seconds (process running for 0.885)

我们可以在日志 Started DemoApplication in 0.722 seconds 看到启动耗时比直接启动少了将近 1 秒。效果还是非常明显的。

四、总结

CDS、CRaC 和 GraalVM,这三种技术都有助于提高Java程序的启动速度,但它们的应用场景和优化方式有所不同。CDS 通过共享类数据来加速启动,CRaC 通过运行时优化来提升性能,而 GraalVM 则通过 AOT 编译来实现快速启动和高效运行。作为开发者,我们可以根据具体需求选择合适的技术来优化 Java 程序的启动时间。

PIG AI | Java大模型应用开发平台重磅发布

我们很高兴向您介绍 PIG AI,一款创新的大语言模型(LLM)应用开发平台。PIG AI 结合了后端即服务(Backend as Service)和 LLMOps 的理念,使开发者能够快速搭建生产级的生成式 AI 应用。


浏览 212
1点赞
评论
收藏
分享

手机扫一扫分享

分享
举报
评论
图片
表情
推荐
1点赞
评论
收藏
分享

手机扫一扫分享

分享
举报