乐趣区

关于java:『Spring-Boot-24新特性』减少95内存占用

节俭 95% 的内存占用,缩小 80% 的启动耗时。


GraalVM 是一种高性能的虚拟机,它能够显著的进步程序的性能和运行效率,非常适合微服务。最近比拟火的 Java 框架 Quarkus 默认反对 GraalVM

下图为 Quarkus 和传统框架(SpringBoot)等比照图, 更快的启动速度、更小的内存耗费、更短的服务响应

Spring Boot 2.4 开始逐渐提供对 GraalVM 的反对, 旨在晋升上文所述的 启动、内存、响应的应用体验

装置 GraalVM

  • 目前官网社区版本最新为 20.3.0,是基于 OpenJDK 8u272 and 11.0.9 定制的,能够了解为 OpenJDK 的衍生版本

  • 官网举荐的是 SDKMAN 用于疾速装置和切换不同版本 JDK 的工具,相似于 nodejs 的 nvm。

应用相似命令即可实现指定版本装置和指定默认版本

sdk install java 11.0.9.hs-adpt
sdk default java 11.0.9.hs-adpt

不过装置过程中须要从国外下载相干资源,笔者在尝试后应用体验并不是很好,所有倡议大家下载指定版本 GraalVM 装置即可(和 JDK 装置形式一样)。

  • 装置胜利查看版本
⋊> ~ java -version                                                      11:30:34
openjdk version "11.0.9" 2020-10-20
OpenJDK Runtime Environment GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06)
OpenJDK 64-Bit Server VM GraalVM CE 20.3.0 (build 11.0.9+10-jvmci-20.3-b06, mixed mode, sharing)

装置 native-image

native-image 是由 Oracle Labs 开发的一种 AOT 编译器,利用所需的 class 依赖项及 runtime 库打包编译生成一个独自可执行文件。 具备高效的 startup 及较小的运行时内存开销的劣势

但 GraalVM 并未内置只是提供 gu 装置工具,须要咱们独自装置。

- 切换到 jdk 的装置目录
⋊> ~ cd $JAVA_HOME/bin/

- 应用 gu 命令装置
⋊>  ./gu install native-image

初始化 Spring Boot 2.4 我的项目

  • Spring Initializr 创立 demo 我的项目
curl https://start.spring.io/starter.zip -d dependencies=web \
           -d bootVersion=2.4.1 -o graal-demo.zip
  • 先看一下启动基准数据,单纯运行空我的项目 须要 1135 ms 秒
java -jar demo-0.0.1-SNAPSHOT.jar


engine: [Apache Tomcat/9.0.41]
2020-12-18 11:48:36.856  INFO 91457 --- [main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2020-12-18 11:48:36.856  INFO 91457 --- [main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 1135 ms
  • 内存占用状况
ps aux | grep demo-0.0.1-SNAPSHOT.jar | grep -v grep | awk '{print $11"\t"$6/1024"MB"}'
/usr/bin/java    480.965MB

反对 GraalVM

  • 减少相干依赖, 波及插件较多残缺已上传 Gitee Gist
<!-- 新增的局部, 留神须要减少  spring maven 仓库地址能力下载到 -->
<dependency>
    <groupId>org.springframework.experimental</groupId>
    <artifactId>spring-graalvm-native</artifactId>
    <version>0.8.3</version>
</dependency>
<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context-indexer</artifactId>
</dependency>

<!-- 须要增加 spring maven 仓库下载 spring-graalvm-native-->
<repositories>
  <repository>
      <id>spring-milestones</id>
      <name>Spring Milestones</name>
      <url>https://repo.spring.io/milestone</url>
  </repository>
</repositories>
  • Main 办法批改, 减少属性 proxyBeanMethods = false
@SpringBootApplication(proxyBeanMethods = false)
  • 应用 native-image 构建可执行文件
 mvn -Pnative package
# 构建过程比较慢,日志如下
spring.factories files...
[com.example.demo.demoapplication:93430]    classlist:   4,633.58 ms,  1.18 GB
   _____                     _                             _   __           __     _
  / ___/    ____    _____   (_)   ____    ____ _          / | / /  ____ _  / /_   (_) _   __  ___
  \__ \    / __ \  / ___/  / /   / __ \  / __ `/         /  |/ /  / __ `/ / __/  / / | | / / / _ \
 ___/ /   / /_/ / / /     / /   / / / / / /_/ /         / /|  /  / /_/ / / /_   / /  | |/ / /  __/
/____/   / .___/ /_/     /_/   /_/ /_/  \__, /         /_/ |_/   \__,_/  \__/  /_/   |___/  \___/
        /_/                            /____/

...
[com.example.demo.demoapplication:93430]      [total]: 202,974.38 ms,  4.23 GB
  • 编译后果

在 targe 目录生成 名称为 com.example.demo.demoapplication 可执行文件

  • 启动利用 这里执行的编译后的可执行文件而不是 jar
cd target

./com.example.demo.demoapplication
  • 启动工夫 0.215 seconds
2020-12-18 12:30:40.625  INFO 94578 --- [main] com.example.demo.DemoApplication         : Started DemoApplication in 0.215 seconds (JVM running for 0.267)
  • 看一下内存占用 24.8203MB
ps aux | grep com.example.demo.demoapplication | grep -v grep | awk '{print $11"\t"$6/1024"MB"}'

./com.example.demo.demoapplication    24.8203MB

数据比照

是否引入 GraalVM 内存占用 启动工夫
480.965MB 1135 ms
24.8203MB 215 ms

>>> 源码 https://gitee.com/log4j/pig,欢送署名转载 <<<

退出移动版