SpringBoot新特性:节省百分之95﹪内存占用!

GraalVM是一种高性能的虚拟机,它可以显著的提高程序的性能和运行效率,非常适合微服务。最近比较火的 Java框架 Quarkus 默认支持 GraalVM

Quarkus和传统框架(SpringBoot) 对比,具有更快的启动数据、更小的内存消耗、更短的服务响应

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

GraalVM: https://www.graalvm.org
Quarkus: https://quarkus.io

安装 GraalVM

目前官方社区版本最新为 20.3.0,是基于 OpenJDK 8u272 and 11.0.9 定制的,可以理解为 OpenJDK 的衍生版本

官方推荐的是 SDKMAN 用于快速安装和切换不同版本 JDK 的工具,类似于 nodejs 的 nvm

SDKMAN: https://sdkman.io/install
nvm: https://github.com/creationix/nvm

使用类似命令即可完成指定版本安装和指定默认版本

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

不过安装过程中需要从国外下载相关资源,笔者在尝试后使用体验并不是很好,所有建议大家下载指定版本 GraalVM 安装即可(和 JDK 安装方式一样)

安装成功查看版本:

1
2
3
4
$ java -version
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 的安装目录
1
$ cd $JAVA_HOME/bin/
  • 使用gu命令安装
1
$ ./gu install native-image

初始化 Spring Boot 2.4 项目

  • Spring Initializr 创建 demo 项目
1
2
$ curl https://start.spring.io/starter.zip -d dependencies=web \
-d bootVersion=2.4.1 -o graal-demo.zip

先看一下启动基准数据,单纯运行空项目需要 1135 ms

1
2
3
4
5
$ 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
  • 内存占用情况
1
2
$ 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

  • 增加相关依赖
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
<!-- 新增的部分,注意需要增加 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
1
@SpringBootApplication(proxyBeanMethods = false)

使用 native-image 构建可执行文件

1
$ mvn -Pnative package
1
2
3
4
5
6
7
8
9
10
11
12
#构建过程比较慢,日志如下
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
1
2
3
cd target

./com.example.demo.demoapplication
  • 启动时间 0.215 seconds
1
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
1
2
3
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

Powered by AppBlog.CN     浙ICP备14037229号

Copyright © 2012 - 2021 APP开发技术博客 All Rights Reserved.

访客数 : | 访问量 :