节省 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,欢迎署名转载 <<<

『Spring Boot 2.4新特性』减少95%内存占用的更多相关文章

  1. Spring Boot 2(一):Spring Boot 2.0新特性

    Spring Boot 2(一):Spring Boot 2.0新特性 Spring Boot依赖于Spring,而Spring Cloud又依赖于Spring Boot,因此Spring Boot2 ...

  2. Spring Boot 2.0 新特性和发展方向

    以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...

  3. 【2.0新特性】Spring Boot 2.0新特性

    以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Java 6 和 7 不再支持. 内嵌容器包结构调整 为了支持reactive使用场景,内嵌的容器包结构被重构了 ...

  4. Spring Boot实践——Spring Boot 2.0 新特性和发展方向

    出自:https://mp.weixin.qq.com/s/EWmuzsgHueHcSB0WH-3AQw 以Java 8 为基准 Spring Boot 2.0 要求Java 版本必须8以上, Jav ...

  5. Spring Boot 2.0 新特性

    这是一篇总结文章,主要收集 Spring Boot 2.0 相对于 Spring Boot 1.x 的新特性,本章节并不提供实践性质的源代码.在 Spring Boot 系列文章中会持续退出实践章节. ...

  6. Spring Boot 2.3 新特性优雅停机详解

    什么是优雅停机 先来一段简单的代码,如下: @RestController public class DemoController { @GetMapping("/demo") p ...

  7. 原创 Spring Boot 2.3 新特性分层JAR

    背景 在我们实际生产容器化部署过程中,往往会遇到 Docker 镜像很大,部署发布很慢的情况 影响 docker 镜像大小的因素,主要有以下三个方面: 基础镜像的大小 .尽量选择 aphine 作为基 ...

  8. 「Spring Boot 2.4 新特性」启动耗时详细监控

    背景 Spring Boot 项目随着项目开发过程中引入中间件数量的增加,启动耗时 逐渐增加. 笔者在 <Spring Boot 2.4.0 正式 GA,全面拥抱云原生>文章评论下发现了 ...

  9. Spring Boot 2.4 新特性,全新的Cron表达式处理机制

    说起 cron 表达式大家一定不陌生,我们常用来作为定时任务执行策略规则. 在 Spring Boot 框架中 cron 表达式主要配合 @Scheduled 注解在应用程序中使用. 在 Spring ...

随机推荐

  1. golang官方嵌入文件到可执行程序

    目录 前言 示例程序 嵌入文件直接访问 嵌入文件列表 总结 前言 在go官方出嵌入文件的方法前我在网上找过,并且自己还研究过,虽然没有问题,但是既然官方支持还是用起来吧. 看了下go源码embed/e ...

  2. 关于各种Formatting context

    Formatting context 我们把网页看作是由很多个盒子组成的,而这些盒子的展示方式,就是由display这个属性来决定的. 这里出现了一个概念,叫做Formatting context(格 ...

  3. Maven遇到的各种问题

    1.遇到报错-Dmaven.multiModuleProjectDirectory system propery is not set.Check $M2_HOME environment varia ...

  4. SpringBoot(七):SpringBoot中如何使用过滤器(Filter)?

    方式一: 通过注解方式实现: 1.编写一个Servlet3的注解过滤器(和上一章Servlet相似) 贴代码: package com.example.springbootweb.filter; im ...

  5. JavaScript疑难点

    什么是闭包 我个人理解闭包就是函数中嵌套函数,但是嵌套的那个函数必须是返回值,才构成闭包: //标准的闭包 function fn(){ var i=1; return function fnn(){ ...

  6. 后端程序员之路 52、A Tour of Go-2

    # flowcontrol    - for        - for i := 0; i < 10; i++ {        - for ; sum < 1000; {        ...

  7. 剑指 Offer 51. 数组中的逆序对 + 归并排序 + 树状数组

    剑指 Offer 51. 数组中的逆序对 Offer_51 题目描述 方法一:暴力法(双层循环,超时) package com.walegarrett.offer; /** * @Author Wal ...

  8. salesforce零基础学习(一百零一)如何了解你的代码得运行上下文

    本篇参考:https://developer.salesforce.com/docs/atlas.en-us.228.0.apexcode.meta/apexcode/apex_enum_System ...

  9. 还在用crontab? 分布式定时任务了解一下

    前言 日常任务开放中,我们会有很多异步.批量.定时.延迟任务要处理,go-zero中有 go-queue,推荐使用 go-queue 去处理,go-queue 本身也是基于 go-zero 开发的,其 ...

  10. Android实现三角形气泡效果方式汇总

    在开发过程中,我们可能会经常遇到这样的需求样式: 这张图是截取京东消息通知的弹出框,我们可以看到右上方有个三角形的气泡效果,这只是其中一种,三角形的方向还可以是上.下.左.右. 通过截图可以发现,气泡 ...