1995年java诞生时提出了Write Once,Run Anywhere的口号
2018年oracle公开了Graal VM 提出了Run Programs Faster Anywhere的新口号
一 是什么
- Graal VM 被官方称为“Universal VM”和“Polyglot VM”,这是一个在 HotSpot 虚拟机基础上增强而成的跨语言全栈虚拟机,可以作为“任何语言”的运行平台
- 使用Graal VM 可以无额外开销地混合使用这些编程语言,支持不同语言中混用对方的接口和对象,也能够支持这些语言使用已经编写好的本地库文件
- 特点 多用途 + 多语言 包括高性能的即时编译器+提前编译器 + 中间语言解释器
二 云原生时代的java
java诞生时是为了服务于嵌入式设备,但是赶上了web风口。在现在大型单体应用向小型微服务应用架构的潮流下,java展示出来了一些不适应:
- 现实是java面向大规模,长时间的服务端应用设计
- 性能制导 即时编译 GC子系统都是面向长时间运行设计的
- 需要一段时间达到最佳性能(经过充分预热的java程序性能好于C/C++)
- 微服务对程序新的方面提出了更高要求 比如 容器亲和度 启动速度
- 启动一个java程序 需要VM初始化-应用程序初始化-字节码解释执行-JIT编译热点函数-执行native code
- 生态丰富是java的优势也是 妨碍 java变革的负担。java发布时做出了二进制向后兼容性的保证 ,虽然可以程序通过直接升级JDK的方式提高性能,但也对JDK发展造成沉重的负担
不同
- 大型单体应用的性能度量(HotSpot JIT)
- Peek Throughput (吞吐量)
- Reduced Latency (延迟)
- Memory Footprint (内存消耗)
- 微服务的性能度量(Graal VM AOT)
- Peek Throughput (吞吐量)
- Reduced Latency (延迟)
- Memory Footprint (内存消耗)
- Startup Speed (启动速度)
- Package Size (包/镜像大小)
具体体现
- 在serverless下传统SpringBoot项目从启动到响应需要400ms 而native程序只需要4ms
- 耗时在于装配 具体 与 @ConditionalOnClass 有关
- 一个最基本的java程序在运行时需要装配409个类,大概需要185ms,而一个SpringBoot程序则会1000+类 耗时更久
问题的根源
- java是VM Base 而不是 Native Base
- java代码是动态,开放而不是 静态 封闭的
- JIT 与 AOT
- JIT优点
- 性能分析制导优化
- 激进预测性优化
- 链接时优化
- AOT优点以及问题
- 无需担心编译用时
- 不支持运行时class loading
- 动态代理 以及运行时字节码生成
- 反射(需要显式指明)
- JNI JCA
- JIT优点
- 解释执行与编译执行
- 当测试循环主体只执行一次时,编译带来的性能损失要高于获得的性能提升
解决方案
- 革命派
- 革掉java和java生态的命,创造新形态 比如Golang
- 激进派
- 摒弃传统java生态,在Graal VM上另起炉灶开发新java应用 比如Quarkus Micronaut
- 温和派
- 尽可能保留java技术资产,自动化迁移至Graal VM Native应用
- 保守派
- 在原有java生态上做改进,朝着微服务 云原生环境迈进
- 比如AppCDS (Application Class Data Sharing)
总结:
- 基本思想
- 将java字节码编译成自举的本地二进制可执行文件
- 核心原则
- 封闭性假设,保证所有运行时内容必须在编译时可见,并编译到native image
- 主要优点
- 启动性能
- 内存消耗小
- 多语言支持
- 主要缺点
- 不能完全支持java的动态特性
- 不再具有平台无关性
其他
Graal VM native support needs to be sustainable and maintainable, that’s why we do not want to maintain fragile pathches for the whole JVM ecosystem. The ecosystem of libraries needs to support it natively. —— Sébastien Deleuze,DEVOXX 2019
不过,必须客观地说明一点,尽管 Graal VM 在启动时间、空间占用、内存消耗等容器化环境中比较看重的方面确实比 HotSpot 有明显的改进,尽管 Graal VM 可以放心大胆地使用重负载的优化手段,但如果是处于长时间运行这个前提下,至少到目前为止,没有任何迹象表明它能够超越经过充分预热后的 HotSpot。在延迟、吞吐量、可监控性等方面,仍然是 HotSpot 占据较大优势,下图引用了 DEVOXX 2019 中 Graal VM 团队自己给出的 Graal VM 与 HotSpot JIT 在各个方面的对比评估
如果 Java 语言或者 HotSpot 虚拟机真的有被取代的一天,那从现在看来 Graal VM 是希望最大的一个候选项,这场革命很可能会在 Java 使用者没有明显感觉的情况下悄然而来,Java 世界所有的软件生态都没有发生丝毫变化,但天下第一的位置已经悄然更迭。
三 现在
- Spring团队表示 将在Spring Boot 3 原生支持 Native模式 ,与Spring FrameWork 6紧密结合
- 预计2022年底全面启用SpringBoot Native模式
- 2022/3/22 Spring Native 支持 M1 Architecture (AArch 64)
四 Hello World
在MacBooK Pro 14(M1 Pro)上
- 环境如下 (aarch64 )
Graal VM下 (open JDK 17)
- 使用JVM (0.533 s)
- Native (0.153 s)
HotSpot下 (Zulku JDK 9)
- 使用JVM(0.658 s)
在Windos机器上( i5 9300H)
HotSpot(open JDK 8)
- 使用JVM ( 1.93 s)