GraalVM上的多语言混合开发

上篇文件我们介绍了GraalVM强大的静态编译功能,能够让Java应用程序摆脱虚拟机的束缚,像其它本地编译的应用一样直接运行。那么GraalVM的神奇之处仅限于此吗?今天我们再来看看它的另一个重要特性—多语言混合开发

多语言平台

Java并不是唯一运行在JVM上的语言,这个我们都应该比较清楚了,比如Kotlin,Scala,Groovy这些其实都是运行在JVM之上的。这样语言不管上层语法千差万别,但最终都会被编译器(javac,kotlinc等)编译成符合JVM规范的字节码,所以它们能跑在JVM上,并且可以相互调用其实并不让人意外。

理论上任何上层语言都能够通过一定的转换,变成符合标准JVM规范的字节码,从而运行在JVM平台之上,但编写这样的编译器的成本非常高,而且受限于JVM字节码的结构何规范,有些语言特性可能也没办法很好的支持。因此GraalVM实现多语言平台采用了另一种方式,绕开了JVM字节码的限制,我们先来看一下官方给的架构图:
在这里插入图片描述
在这张图上,不但GraalVM不但能跑Kotlin,Scala这类传统的JVM语言,还有JS, Python, Ruby这样的脚本语言,甚至还有C和C++ 。初看起来确实很让人惊讶,不过先别急,我们慢慢来分析一下其中的原理。这张图底层的部分,Graal编译器,JVMCI,Hotspot JVM上一篇文章都讲过了,不理解的同学可以再翻一下之前的文章。我们重点来看一下Truffle这个新出现的框架。

这个东西显然是实现多语言平台的关键,官方对它的定义有点拗口,简单的说它是一个用于开发某种语言(比如JavaScript)的解释器的一套工具和框架,让不同的语言能够方便的实现自己的解释器,从而将各语言的源代码都能够解析成一种统一的数据格式,而这种数据格式是一种self-modifying Abstract Syntax Trees(AST,抽象语法树)。为了便于理解,你可以简单的认为它就是其它语言编译后的字节码(都是某种中间格式),Truffle框架还提供运行层面的支持,可以直接解释执行这样的AST,从而实现多语言运行在JVM之上。因此要将一门现有语言搬到GraalVM上来运行,你只需要使用Truffle框架为该门语言编写一个Interpreter(解释器),是不是看起来很简单?GraalVM官方目前也已经实现了包括JavaScript,Python等在内的多个Truffle解释器(GraalJS,GraalPython等),可以直接供开发者使用。

在这里插入图片描述
如果仅仅是这样,那么大家可能觉得这仅仅只是一个小玩具而已,毕竟通过解释器来执行脚本语言性能肯定很拉跨,完全无法和原生平台的执行效率相提并论。但不要小看GraalVM的雄心壮志,我们都知道JVM经过这么多年的发展,在编译优化,内存管理(垃圾回收)这些方面都有着非常强悍的积累(go的垃圾回收器的性能表现就长期不如Java),这才是运行在JVM之上的语言的真正的优势所在。但怎么让这些解释执行的脚本语言也享受JVM的优化呢?答案是JIT,JIT的概念这里就不多介绍了,我们再来看一张图,以Javascript和Java为例,看看它们在GraalVM上的执行细节

运行细节

先来看Java的执行路径,首先由javac编译成字节码,然后JVM的解释器一边解释执行,一边收集运行时信息,当部分代码达到阙值的时候(调用次数等统计指标)就会触发JIT编译,JVM将此部分代码通过Graal编译器编译成本地机器码,然后替换自身缓存中的此部分字节码,从而提升该部分代码的执行效率。JVM和JIT编译器之间通过JVMCI规范的接口进行交互,所以这里的Graal编译器也可以替换成传统的C1或者C2编译器。Kotlin,Scala等语言的执行方式也基本是这样。

再看一下Javascript,源码首先会被基于Truffle实现的JS解释器转换成内存中的AST格式,然后就可以被Truffle内部的解释器解释执行了,而Truffle也会像JVM一样,统计收集运行时信息,并将热点代码发送给Graal编译器去编译成本地机器码,最终将编译好的机器码替换AST中的相同部分,所以现在明白为什么叫做self-modifying Abstract Syntax Trees吧,这个AST树是能够自修改的。所以基于Truffle框架执行的三方脚本语言,也能享受到JIT编译器的各种优化,性能比纯解释执行要高出很多。而且Truffle是一个完全用Java编写的框架,所以它可以直接运行于底层的JVM之上。

上面的图还有一个Graal IR的东西,这个是个什么东西呢?这个主要是为了让Graal编译器能够实现语言无关的特性而使用的一种中间表示形式,不管是JAVA的字节码还是Javascript的AST,在Graal编译器内部都会被表示为Graal IR,然后对这种格式进行编译优化,最终形成机器码。

通过精心的设计和优化,在GraalVM上执行三方语言,性能已经非常接近原生平台了,部分场景下甚至会超过原生的平台。下图就是GraalVM官方对于Javascript执行性能与V8(公认最强的JS执行引擎)的对比:
在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/bicheng/42623.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

����: �Ҳ������޷��������� javafx.fxml ԭ��: java.lang.ClassNotFoundException解决方法

如果你出现了这个问题,恭喜你,你应该会花很多时间去找解决方法。别问我怎么知道的... 解决方法: 出现乱码的原因:配置vm时 这些配置看似由有空格,换行,实则没有。所以解决办法就是,重新配置你…

防火墙概述

1、防火墙 防火墙顾名思义就是防止火灾发生时,火势烧到其它区域,使用由防火材料砌的墙。在网络安全中,防火墙的作用就是保护本地网络不受到外部网络或恶意程序的伤害。 防火墙的核心任务是控制和防护,即通过安全策略识别流量并做…

前端面试题17(js快速检索方法详解)

在前端JavaScript中,快速检索数据通常涉及到数组或对象的搜索。这里我会介绍几种常见的快速检索方法,并提供相应的代码示例。 1. 数组的find和findIndex方法 find: 返回数组中满足条件的第一个元素的值。findIndex: 返回数组中满足条件的第一个元素的索…

【mindspore进阶】02-ResNet50迁移学习

Mindspore 应用(2)ResNet50迁移学习 在实际应用场景中,由于训练数据集不足,所以很少有人会从头开始训练整个网络。普遍的做法是,在一个非常大的基础数据集上训练得到一个预训练模型,然后使用该模型来初始化…

MongoDB:掌握核心常用命令语句,精通数据操作

标题:MongoDB:掌握核心命令,精通数据操作 前言: MongoDB 是一种非关系型数据库,以文档为中心,使用 JSON 格式的 BSON 来存储数据。它具有高可用性、高性能和易于扩展的特点,被广泛应用于各种规…

Laravel: 优雅构建PHP应用的现代框架

在PHP开发生态中,Laravel是一个广受欢迎的现代Web应用框架。以其优雅、简洁的代码风格和强大的功能著称,Laravel使得开发复杂应用变得简单而高效。本文将带你深入了解Laravel框架的核心特性、优势以及如何开始使用这个框架。 Laravel框架简介 Laravel是…

接口(interface)中定义 `default` 方法

在 Java 8 及以后版本中,接口(interface)中可以定义 default 方法。default 方法允许接口提供一个默认的实现,使得接口不仅仅是方法签名的集合,也可以包含方法的具体实现。这一特性提供了更大的灵活性和向后兼容性。以…

张量分解(2)——张量运算(内积、外积、直积、范数)

🍅 写在前面 👨‍🎓 博主介绍:大家好,这里是hyk写算法了吗,一枚致力于学习算法和人工智能领域的小菜鸟。 🔎个人主页:主页链接(欢迎各位大佬光临指导) ⭐️近…

MATLAB贝叶斯线性回归模型案例

采用辛烷值数据集“spectra_data.mat”(任意数据集均可),介绍贝叶斯线性回归模型的构建和使用流程。 运行结果如下: 训练集预测精度指标如下: 训练集数据的R2为: 1 训练集数据的MAE为: 0.00067884 训练集数据的RMSE为: 0.0008893…

STM32点灯闪烁

stm32c8t6引脚图 开发板引脚图 GPIO端口的每个位可以由软件分别配置成 多种模式。 ─ 输入浮空 ─ 输入上拉 ─ 输入下拉 ─ 模拟输入 ─ 开漏输出 ─ 推挽式输出 ─ 推挽式复用功能 ─ 开漏复用功能 配置GPIO端口步骤:开启时钟->使用结构体设置输出模式…

水仙花数算法

一、水仙花的传说 希腊神话故事 传说希腊神话里,美少年纳西索斯(Narcissus)是希腊最俊美的男子,无数的少女对他一见倾心,可他却自负地拒绝了所有的人。这当中包括美丽的山中仙女伊可(Echo)。伊可…

分享一些提升效率的办公、学习神器!

分享一些提升效率的办公、学习神器! 文章目录 分享一些提升效率的办公、学习神器! 一、 ✅ 文件搜索工具 Everything:1.1 Everything 主要功能:1.2 Everything 下载地址: 二、 ✅ 文件压缩解压工具 7 - Zip&#xff1a…

AI免费英语学习在线工具:Pi;gpt;其他大模型AI 英语学习智能体工具

1、pi(强烈推荐:可以安卓下载使用) https://pi.ai/talk (网络国内使用方便) 支持实时聊天与语音对话 2、chatgpt(强烈推荐:可以安卓下载使用) https://chat.openai.com/ (网络国内使用不方便&#xf…

2028年企业云存储支出翻倍,达到1280亿美元

根据Omdia的研究,到2028年,企业云存储支出将从去年的570亿美元翻一番以上,达到1280亿美元。该研究分析了基础设施即服务(IaaS)和平台即服务(PaaS)数据中心的收入,作为年度存储数据服…

C++初学者指南-4.诊断---valgrind

C初学者指南-4.诊断—Valgrind Valgrind(内存错误检测工具) 检测常见运行时错误 读/写释放的内存或不正确的堆栈区域使用未初始化的值不正确的内存释放,如双重释放滥用内存分配函数内存泄漏–非故意的内存消耗通常与程序逻辑缺陷有关&#xf…

Halcon 背景网格产品刮伤缺陷检测

* 关闭窗口 dev_close_window ()*关闭程序计数器,图形变量更新,窗口图形更新 dev_update_off ()*设置图像路径 Path : lcd/mura_defects_blur_*读取一张图像 read_image (Image, Path 01)*获取图像大小 get_image_size (Image, Width, Height)*创建一个新窗体 dev_open_window…

Apache Seata应用侧启动过程剖析——注册中心与配置中心模块

本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 本文来自 Apache Seata官方文档,欢迎访问官网,查看更多深度文章。 Apache Seata应用侧启动过程剖析——注册中心与配置中心模块 前言 在Seata的应用侧&#xf…

SpringBoot Elasticsearch painless 查询某个属性是否存在的复杂判断for循环判断,深入理解Painless脚本查询

在使用Spring Boot与Elasticsearch结合进行搜索应用开发时,我们经常会遇到需要对文档中的数组或列表类型字段进行复杂查询的情况。Elasticsearch的Painless脚本语言提供了一种强大的方式来执行这类查询,允许开发者在查询时执行自定义的逻辑判断。 深入理…

强化训练:day13(牛牛冲钻五、最长无重复子数组、重排字符串)

文章目录 前言1. 牛牛冲钻五1.1 题目描述1.2 解题思路1.3 代码实现 2. 最长无重复子数组2.1 题目描述2.2 解题思路2.3 代码实现 3. 重排字符串3.1 题目描述3.2 解题思路3.3 代码实现 总结 前言 1. 牛牛冲钻五   2. 最长无重复子数组   3. 重排字符串 1. 牛牛冲钻五 1.1 题…

【Scrapy】深入了解 Scrapy 中间件中的 process_spider_output 方法

准我快乐地重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 再去做没流着情泪的伊人 假装再有从前演过的戏份 重饰演某段美丽故事主人 饰演你旧年共寻梦的恋人 你纵是未明白仍夜深一人 穿起你那无言毛衣当跟你接近 🎵 陈慧娴《傻女》 Scrapy 是…