11-GraalVM元原生时代的Java虚拟机

2023-12-26 01:52

本文主要是介绍11-GraalVM元原生时代的Java虚拟机,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

文章目录

  • GraalVM诞生的背景
    • Java在微服务/云原生时代的困境
      • 事实
      • 矛盾
    • 问题根源
      • Java离不开虚拟机
    • 解决方案
      • 革命派
      • 保守派
  • GraalVM入门
  • GraalVM特征
  • GraalVM下载和安装
    • GraalVM下载
    • win10安装及配置
    • linux安装及配置
  • GraalVM初体验(Linux)
  • 多语言开发(了解即可、官网有Demo)
    • GraalCompiler
    • Graal 和 C2 的区别
    • GraalVM与SpringBoot

GraalVM诞生的背景

Java在微服务/云原生时代的困境

事实

Java总体上是面向大规模、长时间的服务端应用而设计的。
严(luō)谨(suō)的语法利于约束所有人写出较一致的代码,利于软件规模的提升;
但是像即时编译器(JIT)、性能优化、垃圾回收等有代表性的特征都是面向程序长时间运行设计的,需要一段时间来达到最佳性能,才能享受硬件规模提升带来的红利。

矛盾

在微服务的背景下,提倡服务围绕业务能力构建,不再追求实现上的严谨一致;
1、单个微服务就不再需要再面对数十、数百GB乃至TB的内存;
2、有了高可用的服务集群,也无须追求单个服务要7×24小时不可间断地运行,它们随时可以中断和更新。
所以微服务对应用的容器化(Docker)亲和度(包容量、内存消耗等)、启动速度、达到最高性能的时间等方面提出了新的要求,这些恰恰是Java的弱项。
比如:现在启动一个微服务项目(Docker运行6个子服务),动不动就1分钟,如下图:
在这里插入图片描述

问题根源

Java离不开虚拟机

所以Java应用启动的时候,必须要启动虚拟机,进行类加载,无论是启动时间,还是占用空间都不是最优解

解决方案

革命派

直接革掉Java和Java生态的性命,创造新世界,譬如Golang

保守派

尽可能保留原有主流Java生态和技术资产,在原有的Java生态上做改进,朝着微服务、云原生环境靠拢、适应。其中最大的技术运用就是GraalVM!

GraalVM入门

GraalVM 是一个高性能 JDK 发行版,旨在加速用Java和其他JVM语言编写的应用程序的执行,并支持 JavaScript、Ruby、Python 和许多其他流行语言(翻译自官网 https://www.graalvm.org/)
在这里插入图片描述

GraalVM想成为一统天下的“最终”虚拟机!而GraalVM要做到原因也很简单:
大部分脚本语言或者有动态特效的语言都需要一个语言虚拟机运行,比如CPython,Lua,Erlang,Java,Ruby,R,JS,PHP,Perl,APL等等,但是这些语言的虚拟机水平很烂,比如CPython的VM就不忍直视,而HotSpotVM是虚拟机的大神级别,如果能用上HotSpot,能用上顶级的即时编译器(JIT)、性能优化、垃圾回收等技术,岂不爽歪歪!

GraalVM特征

  1. GraalVM是一款高性能的可嵌入式多语言虚拟机,它能运行不同的编程语言
  • 基于JVM的语言,比如Java, Scala, Kotlin和Groovy

  • 解释型语言,比如JavaScript, Ruby, R和Python

  • 配合LLVM一起工作的原生语言,比如C, C++, Rust和Swift

  1. GraalVM的设计目标是可以在不同的环境中运行程序
  • 在JVM中

  • 编译成独立的本地镜像(不需要JDK环境)

  • 将Java及本地代码模块集成为更大型的应用

GraalVM下载和安装

GraalVM分成了社区版与企业版(好消息目前都免费!)
企业版肯定比社区版好,所以推荐下载企业版,因为演示的原因,我使用的是20的版本
在这里插入图片描述

GraalVM下载

官网下载地址:
https://www.oracle.com/downloads/graalvm-downloads.html
在这里插入图片描述

win10安装及配置

在这里插入图片描述
在这里插入图片描述
配置时要注意,如果配置不成功,极有可能是windows10中JDK8优先了,解决方案:windows10 修改java环境变量不生效
在这里插入图片描述
在这里插入图片描述
使用 GraalVM Enterprise,您可以将 Java 字节码编译为特定于平台的、自包含的本机可执行文件(本机映像 Native Image),以实现更快的启动和更小的应用程序占用空间。
安装命令如下:

gu install native-image

在这里插入图片描述
在这里插入图片描述
如果是在windows中如果要使用 本机映像 (Native Image)需要安装VC,具体见:另https://www.jianshu.com/p/a5cdf85e4ffa

linux安装及配置

  1. 官网下载安装包,FTP上传至安装目录
    在这里插入图片描述
    在这里插入图片描述

  2. 解压安装包
    在这里插入图片描述
    在这里插入图片描述

  3. 配置环境变量
    在这里插入图片描述
    在这里插入图片描述

  4. 使用 GraalVM Enterprise,您可以将 Java 字节码编译为特定于平台的、自包含的本机可执行文件(本机映像 Native Image),以实现更快的启动和更小的应用程序占用空间。
    安装命令如下:
    在这里插入图片描述
    在这里插入图片描述

GraalVM初体验(Linux)

  1. 写一个简单的类
    在这里插入图片描述

  2. 编译->执行
    在这里插入图片描述

  3. 打包成一个本地可执行文件(Native Image功能)
    在这里插入图片描述

这样就会生成一个可执行文件。这个过程我就称之为将Java 字节码编译为特定于平台的、自包含的本机可执行文件(本机映像 Native Image),以实现更快的启动和更小的应用程序占用空间。
更快速的启动:

对比下,通过 time命令来对比
1、通过java 走虚拟机来运行
在这里插入图片描述

2、不通过java虚拟机直接运行
在这里插入图片描述

对比发现,通过这种方式启动一个简单的类,启动速度要快很多。
阿里早就通过这种方式加快容器的启动速度,直接启动速度提升20倍
https://www.graalvm.org/native-image/
在这里插入图片描述

另外这种可执行文件是不需要JDK的环境的,所以可以非常方便的完成快速的容器化部署,符合云原生的要求,例如:
我们把这个可执行文件拷贝到另外一台没有任何JDK的环境的服务器上,照样可以运行。
在这里插入图片描述

graal 的 aot 属于“GraalVM ”中的一项技术。

Ahead-of-time compile(提前编译),他在编译期时,会把所有相关的东西,包含一个基底的 VM,一起编译成机器码(二进制)。

好处是可以更快速的启动一个 java 应用(以往如果要启动 java程序,需要先启动 jvm 再载入 java 代码,然后再即时的将 .class 字节码编译成机器码,交给机器执行,非常耗时间和耗内存,而如果使用AOT,可以取得一个更小更快速的镜像,适合用在云部署上)

多语言开发(了解即可、官网有Demo)

GraalCompiler

Graal Compiler是GraalVM与HotSpotVM(从JDK10起)共同拥有的服务端即时编译器,是C2编译器的替代者。
C2还存在一些小BUG,例如:

public class C2Bug {public void test() {int i = 8;while ((i -= 3) > 0);System. out .println("i = " + i);}public static void main(String[] args) {C2Bug c2bug = new C2Bug();for (int i = 0; i < 50_000; i++) {c2bug.test();}}}

在这里插入图片描述

使用-Xint 参数强制虚拟机运行于只有解释器的编译模式,就不会出现问题。
在这里插入图片描述

另外把循环次数降低,降低到5000次,就不会触发JIT,就不会触发C2的优化也不会出现问题。
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

即时编译器是 Java 虚拟机中相对独立的模块,它主要负责接收 Java 字节码,并生成可以直接运行的二进制码。
传统情况下(JDK8),即时编译器是与 Java 虚拟机紧耦合的。也就是说,对即时编译器的更改需要重新编译整个 Java 虚拟机。这对于开发相对活跃的 Graal 来说显然是不可接受的。
为了让 Java 虚拟机与 Graal 解耦合,我们引入了Java 虚拟机编译器接口(JVM Compiler Interface,JVMCI),将即时编译器的功能抽象成一个 Java 层面的接口。这样一来,在 Graal 所依赖的 JVMCI 版本不变的情况下,我们仅需要替换 Graal 编译器相关的 jar 包(Java 9 以后的 jmod 文件),便可完成对 Graal 的升级。

Graal 和 C2 的区别

Graal 和 C2 最为明显的一个区别是:Graal 是用 Java 写的,而 C2 是用 C++ 写的。相对来说,Graal 更加模块化,也更容易开发与维护,毕竟,连C2的开发者都不想去维护C2了。

许多人会觉得用 C++ 写的 C2 肯定要比 Graal 快。实际上,在充分预热的情况下,Java 程序中的热点代码早已经通过即时编译转换为二进制码,在执行速度上并不亚于静态编译的 C++ 程序。

Graal 的内联算法对新语法、新语言更加友好,例如 Java 8 的 lambda 表达式以及 Scala 语言。

例如:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

GraalVM与SpringBoot

2021年03月11日官方宣布的Spring Native只是beta版本,请不要用于生产环境!!!

来谈谈 GraalVM的未来发展
spring 6.0和spring boot3.0都会基于jdk17构建,spring官方也写的很清晰,会继续维护和升级spring 2.0的版本,如果有人不愿意升级,一样可以使用老的版本。
spring 6.0和spring boot3.0总体来说是彻底拥抱aot,让spring native变得更加流行,所以在Spring6与SpringBoot3广泛之前spring native还肯定不是主流而已。
同时jdk17也没有写完loom,代表着没有协程,性能方面比有协程jdk差远了。比如阿里开源的jdk8,11,就有非侵入式携程,在高并发项目中性能比jdk17要强。
所以到底是Oracle公司在引导Java了,还是有可能国内的公司引导了,这个都不好说!

做一个预测
java的协程框架未来很大可能性是阿里等公司主导,而不是Oracle,这个是因为国内的软件行情的原因(高并发项目多)
而云原生的虚拟机则应该是Oracle公司主导,因为国外开发者,大多不会强制限定一定是Java语言,喜欢多语言开发,所以应该来说比较受欢迎,而国内则不同。

这篇关于11-GraalVM元原生时代的Java虚拟机的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/537738

相关文章

Java中流式并行操作parallelStream的原理和使用方法

《Java中流式并行操作parallelStream的原理和使用方法》本文详细介绍了Java中的并行流(parallelStream)的原理、正确使用方法以及在实际业务中的应用案例,并指出在使用并行流... 目录Java中流式并行操作parallelStream0. 问题的产生1. 什么是parallelS

Java中Redisson 的原理深度解析

《Java中Redisson的原理深度解析》Redisson是一个高性能的Redis客户端,它通过将Redis数据结构映射为Java对象和分布式对象,实现了在Java应用中方便地使用Redis,本文... 目录前言一、核心设计理念二、核心架构与通信层1. 基于 Netty 的异步非阻塞通信2. 编解码器三、

SpringBoot基于注解实现数据库字段回填的完整方案

《SpringBoot基于注解实现数据库字段回填的完整方案》这篇文章主要为大家详细介绍了SpringBoot如何基于注解实现数据库字段回填的相关方法,文中的示例代码讲解详细,感兴趣的小伙伴可以了解... 目录数据库表pom.XMLRelationFieldRelationFieldMapping基础的一些代

一篇文章彻底搞懂macOS如何决定java环境

《一篇文章彻底搞懂macOS如何决定java环境》MacOS作为一个功能强大的操作系统,为开发者提供了丰富的开发工具和框架,下面:本文主要介绍macOS如何决定java环境的相关资料,文中通过代码... 目录方法一:使用 which命令方法二:使用 Java_home工具(Apple 官方推荐)那问题来了,

Java HashMap的底层实现原理深度解析

《JavaHashMap的底层实现原理深度解析》HashMap基于数组+链表+红黑树结构,通过哈希算法和扩容机制优化性能,负载因子与树化阈值平衡效率,是Java开发必备的高效数据结构,本文给大家介绍... 目录一、概述:HashMap的宏观结构二、核心数据结构解析1. 数组(桶数组)2. 链表节点(Node

Java AOP面向切面编程的概念和实现方式

《JavaAOP面向切面编程的概念和实现方式》AOP是面向切面编程,通过动态代理将横切关注点(如日志、事务)与核心业务逻辑分离,提升代码复用性和可维护性,本文给大家介绍JavaAOP面向切面编程的概... 目录一、AOP 是什么?二、AOP 的核心概念与实现方式核心概念实现方式三、Spring AOP 的关

详解SpringBoot+Ehcache使用示例

《详解SpringBoot+Ehcache使用示例》本文介绍了SpringBoot中配置Ehcache、自定义get/set方式,并实际使用缓存的过程,文中通过示例代码介绍的非常详细,对大家的学习或者... 目录摘要概念内存与磁盘持久化存储:配置灵活性:编码示例引入依赖:配置ehcache.XML文件:配置

Java 虚拟线程的创建与使用深度解析

《Java虚拟线程的创建与使用深度解析》虚拟线程是Java19中以预览特性形式引入,Java21起正式发布的轻量级线程,本文给大家介绍Java虚拟线程的创建与使用,感兴趣的朋友一起看看吧... 目录一、虚拟线程简介1.1 什么是虚拟线程?1.2 为什么需要虚拟线程?二、虚拟线程与平台线程对比代码对比示例:三

Java中的.close()举例详解

《Java中的.close()举例详解》.close()方法只适用于通过window.open()打开的弹出窗口,对于浏览器的主窗口,如果没有得到用户允许是不能关闭的,:本文主要介绍Java中的.... 目录当你遇到以下三种情况时,一定要记得使用 .close():用法作用举例如何判断代码中的 input

Spring Gateway动态路由实现方案

《SpringGateway动态路由实现方案》本文主要介绍了SpringGateway动态路由实现方案,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随... 目录前沿何为路由RouteDefinitionRouteLocator工作流程动态路由实现尾巴前沿S