写点什么

Java on Truffle:实现真正的元循环

一种全新的、非常令人兴奋的运行 Java 代码的方式

2021 年 2 月 10 日

Java on Truffle:实现真正的元循环

GraalVM 21.0 引入了一个新的 JVM 实现 Java on Truffle,这是一个使用 Java 编写的 Java 虚拟机,从而提供了一种在 GraalVM 上运行 Java 代码的新方式。


本文最初发表于 GraalVM 的Medium博客站点,经原作者 Oleg Šelajev 授权由 InfoQ 中文站翻译分享。


到目前为止,GraalVM 已经提供了两种运行 Java 程序的方式:组合使用 Java HotSpot VM 和 GraalVM JIT(just-in-time)编译器,以及使用 GraalVM Native Image 编译成原生可执行文件。


如今,我们很高兴地宣布一种在 GraalVM 运行 Java 的新方法。GraalVM 21.0 引入了一个新的可安装的组件,叫做espresso,它提供了一个使用 Java 编写的 JVM 实现。


Java on Truffle 在 Java 架构中的位置


Espresso 使得通过 Truffle 框架运行 Java 代码成为可能,从而将 Java 提升到与 GraalVM 所支持的其他语言相同的级别。

尝试运行


尝试 Java on Truffle 是非常简单直接的。它可以使用 gu 命令,作为一个组件安装到基础 GraalVM 发行版中。


gu install espressogu install -L espresso-installable.jar # if downloaded manually
复制代码


安装之后,要在 Java on Truffle 运行你最喜欢的应用,只需要为java命令传递-truffle参数即可。


java -truffle -jar myApp.jar
复制代码


请下载 Java on Truffle 并尝试一下。这里有一些带有指令的示例应用,阐述了 Java on Truffle 的特殊功能。


注意,当前 Java on Truffle 的性能并不代表它在不远的将来的能力。目前它的峰值性能要比常规 JIT 模式下运行相同的代码慢好几倍。另外,预热也还没有进行优化。在这个初始发布版本中,我们完全专注于功能、兼容性,并让 Java on Truffle 开源,使其能够在更广大的社区中得到应用。


预计在我们即将发布的每个 21.x 版本中,性能(包括预热性能和峰值性能)将会得到迅速提升


现在,我们更加详细地看一下 Java on Truffle 是什么并探索一些它提供帮助的典型用例,尝试将该项目放到更大的 GraalVM 和 Java 生态系统中。

Java on Truffle

Java on Truffle 是一个 JVM 实现,它使用了 Truffle 语言实现框架。它提供了 Java 虚拟机所有的核心组件:


  • 字节码解释器

  • 字节码校验器

  • 单程(Single-pass)的 class 文件解析器

  • 简单的对象模型

  • 使用 Java 语言编写的 Java 原生接口(Java Native Interface,JNI)实现

  • 使用 Java 实现的 Java 虚拟机

  • Java Debug Wire Protocol(JDWP)


这个 JVM 实现有很重要的一点就是它是使用 Java 编写的。Java on Truffle 是基于 Java 的 Java(Java on Java)。自托管是 Java 虚拟机研究和开发领域的圣杯。


它所能做的就是运行 Java 程序。当然,它也可以运行用其他 JVM 语言编写的程序。从上面的列表我们可以看出,它还支持调试协议,所以我们也可以使用它调试 Java 应用。


Java on Truffle 能够用于基于 Java 8 和 Java 11 的 GraalVM 发行版,所以从技术上来讲,你可以使用它来替代自己所选择的 JVM。Java on Truffle 目前是实验性的,速度还不是很快,所以现在不建议将其用于生产环境的工作负载,但是我们可以探索一下使用 Java on Truffle 运行应用程序都能实现哪些特性。

基于 Java 的 Java

正如我们在前文所描述的,Java on Truffle 是使用 Java 实现的。它是一个虚拟机实现,所以为了实际运行 Java 代码,它需要访问类库以及 JDK 提供的本地库和方法。Java on Truffle 重用了 GraalVM 分发版的 JAR 和本地库。



因为它是使用 Java 实现的并且能够运行 Java,这使得 Java on Truffle 具有了非常有意思的特性:它可以运行自己!事实上, Java on Truffle 是一个元循环(metacircular)的虚拟机,它可以嵌套运行自己好几层(不过每次都会越来越慢)。


作为一个 Java 程序,它有很多优势。其中之一就是能够使用原生镜像编译成原生的可执行文件,在后面的章节中我们将会讨论一个很有意思的用例。


另外一个优势就是,对于 Java 开发人员来说,代码非常友好和熟悉,易于理解。读者可以考虑去 GitHub 仓库查看它的源码。你的日常工具适用于它,你的 IDE 支持它,你可以像探索其他 Java 依赖那样去探索它的代码。这种透明度和熟悉度能够让 Java on Truffle 更加高效地应对变化。

将 Java 11 嵌入到 Java 8 中


Java on Truffle 实际就是一个 JVM,但它也是一个 Java 程序,这意味着你可以在其他 Java 程序中运行它。这就为将应用程序中的不同组件进行分割开辟了一个很有趣的途径。举例来说,如果你将 Java on Truffle 指向一个 JDK 11,那么它就能运行 Java 11。如果访问 Java 8,那么它就会成为 Java 8。如果你同时拥有这两个发行版的话,那么你就可以在 Java 8 的环境中运行 Java on Truffle,并使用它来运行 Java 11 字节码,反之亦然。如果有个库只能用于 Java 8,那么你可以迁移至更新的基础 JDK,并且通过一些编程方面的努力让这个特定的库依然能够运行,这需要建立一种互操作性,在相同的 Java 进程中建立兼容的 JDK 8 环境。

混合 AOT 和 JIT


因为 Java on Truffle、Truffle、GraalVM 编译器和运行 Java on Truffle 的所有其他必要的组件都是使用 Java 编写的,所以我们能够构建一个包含运行 Java on Truffle 基础设施的原生镜像可执行文件。


这意味着,我们可以基于 Java 应用,将一个 JVM 构建到它的里面,然后要么在 JVM 上运行该应用,要么以原生镜像的方式运行该应用。需要注意,在后面的情况中,Java on Truffle 实际上可以执行任意的 Java 代码,这些代码不一定需要在构建的时候就得知道。


没错,Java on Truffle 可以将 JIT 编译器和动态 Java 运行时用到一个提前编译的二进制文件中。


Java on Truffle 允许为使用原生镜像构建的应用添加动态语言的特性


我们准备了一个样例应用来阐述这个理念。这是一个 JShell 实现的样例,它接受一个常规的 JShell 应用,该应用包含两个组成部分:前端的 CLI 应用和后端的计算引擎,我们将后者替换成了 Java on Truffle 实现。


实际上,它非常整洁地重用了原来实现中的所有类,只需加载它们即可。因此,示例应用程序的原始部分是连接托管 Java 部分和 Java on Truffle 部分的“胶水”代码。


这个示例可以被编译成原生可执行文件,以得到一个二进制文件,由于原生可执行文件的性能特征,它的启动速度比一般的 JShell 要快,而且仍然可以执行我们扔给它的 Java 代码。


下面是 Java on Truffle 实现的 JShell 加载并启动俄罗斯方块游戏的截图。



混合 AOT 和 JIT 对于那些不能利用原生镜像性能改进的应用程序来说是一个非常棒的可选方案,因为这些应用的功能依赖于动态代码,而动态代码不容易与原生镜像一起工作。

高级的类重定义


Java on Truffle 有另外一项很酷的特性,比 HotSpot 更强大,这就是增强的热替换(Hot Swap)能力:在调试会话中,运行时改变类。


GraalVM 21.0 支持如下的变化:


  1. 添加和移除方法

  2. 添加和移除构造器

  3. 从接口中添加和移除方法

  4. 改变方法的访问修饰符

  5. 改变构造器的访问修饰符

  6. Lambda 的变化

  7. 添加新的匿名内部类

  8. 移除匿名内部类


未来将会使热替换更强大的是支持对类字段的变化。该特性正在进行中,会在未来的释放版本中添加进来。


在 IntelliJ IDEA 调试器中重新加载修改的类


这个搭建过程与 HotSpot 相同:启动调试器、修改代码、重新编译类、在 IDE 调试器中点击“Reload the classes”并使用新代码恢复程序运行,下一次变更的代码就会生效。

GraalVM 生态系统的支持


对于 GraalVM 语言从 Truffle 框架中获取的开发人员工具支持来说,Java on Truffle 会使它们从中收益。


例如,你可以在运行应用的时候,使用某些java -truffle --cpusampler,这样的话就能让采样剖析器(profiler)在代码上运行。我们还可以启用跟踪剖析器或内存跟踪器,从而告诉我们代码的哪个部分产生了更大的内存压力。


生态系统的另一个方面是支持的语言。Java on Truffle 允许我们创建多语言程序,不同的组件用不同的语言编写。关于如何加载用其他语言编写的代码、在不同语言之间导出和导入对象等细节,超出了本文的范围,但细节可以从文档中找到

下一步的计划


GraalVM 21.0 是 Java on Truffle 的初始版本。现在它是一个实验性的组件,在接下来的版本中我们计划对它进行重大改善。


它有很多需要改进的地方,从支持 javaagents,到与其他语言的互操作协议方面提供更好的实现,重大的性能改进等等。


我们将致力于这些和其他方面的改进,并且会非常乐意听到任何反馈、特性请求、潜在的用例、发现的问题和当前版本的不足之处。你可以通过SlackGitHubTwitter分享你的反馈。要想开始学习它,请前往 graalvm.org/java-on-truffle


Java on Truffle 是一种全新的、非常令人兴奋的运行 Java 代码的方式。请了解并考虑一下它所带来的可能性。

2021 年 2 月 10 日 12:136795
用户头像
蔡芳芳 InfoQ高级编辑

发布了 531 篇内容, 共 247.8 次阅读, 收获喜欢 1555 次。

关注

评论 1 条评论

发布
用户头像
Enable the Java on Truffle execution mode. From the main menu select Run -> Run… -> Edit Configurations > Environment. Put the -truffle -XX:+IgnoreUnrecognizedVMOptions command in the VM options field and press Apply.
It is necessary to specify -XX:+IgnoreUnrecognizedVMOptions because Intellij automatically adds a -javaagent argument which is not supported yet.
2021 年 02 月 22 日 11:50
回复
没有更多了
发现更多内容

Linux学习-2020.05.11

Flychen

ShedLock:一个轻量级的定时任务协调组件

kk

定时任务 shedlock

给应届毕业生们的七点建议

Neco.W

大学生日常 工作 应届毕业

C语言if分支结构

C语言技术网-码农有道

C语言 C语言if分支结构

DDD 实践手册(6. Bounded Context - 限界上下文)

Joshua

企业架构 设计模式 领域驱动设计 DDD 架构模式

“随大流”的你是不会成功的

小天同学

个人成长 思考 写作平台 感悟 坚持

【解析+示例】2种方法,通过SpreadJS在前端实现甘特图

Geek_Willie

前端开发 甘特图 SpreadJS 表格控件

NIO 看破也说破(三)—— 不同的IO模型

小眼睛聊技术

Java 学习 深度思考 程序员 架构

目光聚集之处,金钱必将追随

Tom

学习 个人成长 思考 读书

危机过后,「表格文档协同」需要具备什么能力?

Geek_Willie

前端开发 开发者工具 Excel

接口限流算法有哪些,看完这篇又能和面试官互扯了~

不才陈某

Java 分布式 后端

从技术层面理解对于区块链技术的10.24集体学习讲话

MaxHu

区块链 智能合约 以太坊 加密货币 去中心化网络

C语言运算符

C语言技术网-码农有道

C语言 运算符

如何扩大我们的英语词汇量

七镜花园-董一凡

学习

追光逐影:读《我们这一代》

北风

认识数据产品经理(二 数据产品经理的稀缺性)

马踏飞机747

大数据 互联网 数据分析 产品经理

对话 CTO | 喜茶也有 CTO?听陈霈霖讲讲茶饮中的技术甜度

ONES 王颖奇

研发管理 CTO 零售

JavaScript 学习笔记——数据类型

zjlulsum

Java 学习 前端 类型推断 入门

Using R for everything: 方差分解(Variation partition)变量筛选与显著性标注

洗衣机用户不会用洗衣机

数据分析 R

工具集系列|值得收藏的几个免费在线学习国外网站

一尘观世界

学习 工具 网站 提升

工具集系列 02|还在为海报设计、LOGO 设计发愁?这些在线工具值得收藏

一尘观世界

效率工具 设计 海报 课程封面 知识付费

当前的经济形势,如何让自己免于风险?

鼎玉谷

Python程序性能分析和火焰图

ElvinYang

每个人都应该知道的性能参数

ElvinYang

对话 CTO | 听快看漫画 CTO 李润超讲重塑漫画产业的技术推动力

ONES 王颖奇

研发管理 CTO 动画 文化

前端有未来吗?

欧雷

前端 前端开发

Python网络编程socket 简易聊天窗

Flychen

C语言输入和输出

C语言技术网-码农有道

C语言 输入 输出

Try-Catch包裹的代码异常后,竟然导致了产线事务回滚!

码大叔

Java spring 事务

如何高效阅读

ElvinYang

C语言常量、变量和关键字

C语言技术网-码农有道

C语言 常量 变量 关键字

Java on Truffle:实现真正的元循环-InfoQ