@levinzhang
2023-01-10T22:24:08.000000Z
字数 8549
阅读 467
by
GraalVM JIT和AOT编译器的社区版将在2023年转移到OpenJDK中。它们将与OpenJDK的发布节奏和流程保持一致。现有版本、GraalVM企业版和其他GraalVM项目不会进行转移。GraalVM 22.3提供了对JDK 19的实验性支持,并提高了可观测性。Leyden项目将对Java AOT编译进行标准化。
作为GraalVM 22.3版本的一部分,甲骨文详细阐述了将两个GraalVM项目转移至OpenJDK的计划。在2023年的某个时间点,社区版本的即时(Just-in-time,JIT)编译器(“Graal编译器”)和用于原生操作系统可执行文件(“原生镜像”)的提前(Ahead-of-Time,AOT)编译器的代码将会转移至一个新的OpenJDK项目。现有版本、GraalVM企业版功能和其他GraalVM项目将保留在GraalVM中。
甲骨文最初在2022年10月份的JavaOne上宣布了这一举措,但是没有提供具体的细节。在2022年12月中旬,OpenJDK提议新建Galahad项目来实现这次转移。
GraalVM项目是Oracle Labs的一部分,因此不在OpenJDK的管理之下。GraalVM目前每年有四个特性版本,遵循与OpenJDK不同的发布过程。
在OpenJDK,GraalVM Java编译器会与Java的发布节奏保持一致,即每年两个特性更新版本和四个补丁更新版本,每两年一个长期支持版本(Long-Term Support,LTS)。GraalVM OpenJDK项目将使用OpenJDK社区流程,并提交JDK增强提议(JDK Enhancement Proposal,JEP),以便于将其纳入OpenJDK Java版本中。
Graal编译器是使用Java编写的,并在Java运行时环境(Java Runtime Environment,JRE)中使用 Hotspot VM。它取代了使用C++编写的C2 JIT编译器,大多数Java发行版中都包含该编译器。
GraalVM原生镜像AOT编译器会生成原生可执行文件,通常来讲,与运行在JRE中,使用JIT编译器的Java应用相比,它们启动更快,使用的CPU和内存更少并且占用的磁盘空间也更小。这使得Java在云中更具竞争力。GraalVM原生镜像通过删除未使用的代码并预先计算应用的堆快照实现了这些优化,在幕后它会使用Graal编译器。但是,这也将一些Java应用排除在GraalVM原生镜像的使用范围之外。InfoQ最近发表了关于该话题的系列文章。
企业版提供了原生镜像性能的改进,比如用于运行时剖析的Profile-Guided优化,但是它不会转移到OpenJDK中。其他的GraalVM项目也不会进行转移,包括对其他语言(如JavaScript或Python)的支持和Java on Truffle(对整个Hotspot VM的Java替代方案)。
GraalVM社区版本基于GNU通用公开许可证(GNU General Public License)第二版,该协议具有类路径例外(Classpath Exception)条款。许多OpenJDK发行版,包括甲骨文的OpenJDK构建版,都使用同样的许可证。而甲骨文的Java发行版使用的是“甲骨文免费条款和条件(Oracle No-Fee Terms and Conditions)”许可证。甲骨文宣布,“从许可证的角度来看,所有的GraalVM技术都与Java一致[......]",并承诺“在未来几个月内提供更多的细节”。
GraalVM 22.3是2022年最后一个特性发布版本。它对JDK 19提供了实验性的支持,包括来自Loom项目的虚拟线程和结构化并发。对JDK 19的完整支持会在2023年1月底的GraalVM 23.0中提供。
该版本包含了原生可执行文件监控方面的大量改进,这是一个落后于在JRE中运行Java程序的领域。JDK工具jvmstat
现在可以监控原生可执行文件的性能和资源使用,并收集堆转储,以便于使用VisualVM进行探查。原生可执行文件还可以为免费的Java Flight Recorder(JFR)工具记录JavaMonitorEnter
、JavaMonitorWait
和ThreadSleep
事件。
GraalVM原生镜像编译器需要所谓的hint,以获取Java代码中对反射的使用。与Spring和Micronaut框架协作,GraalVM在2022年7月推出了一个面向Java库hint的公共仓库。这个名为“GraalVM Reachability Metadata”的仓库现在已经包含了针对Hibernate、Jetty、JAXB和Thymeleaf的条目。
GraalVM原生镜像AOT编译器在选定的基准测试上要快2到3倍。原生可执行文件运行时需要更少的内存,运行整数的最小/最大操作的操作要更快。在22.2中添加了两个实验性的优化,StripMineCountedLoops
和EarlyGVN
,它们现在已经稳定并默认启用。
原生可执行文件现在可以包含软件物料清单(Software Bill of Material,SBOM),并且通过更好地识别内存使用和内存泄露,调试体验得到了改善。
在GraalVM生态系统的新闻中,当前IntelliJ 2022.3版本提供了调试原生可执行文件的实验性支持,JUnit 5.9.1也提供了注解包含或排除它们。
GraalVM中的Python实现改名为GraalPy。它在兼容性和性能方面有很多改善,就像Ruby的实现TruffleRuby一样。GraalVM中的Python和其他语言得益于Windows上LLVM运行时的实验性可用性。
该GraalVM版本通过一行shell脚本为macOS和Windows提供了新的下载方案:
bash <(curl -sL https://get.graalvm.org/jdk)
Leyden项目是OpenJDK的一项倡议,其使命是“改善Java程序的启动时间、达到性能峰值的时间和占用空间”。甲骨文澄清了GraalVM与该项目的关系:它“计划在OpenJDK社区中发展原生镜像技术,以跟踪Leyden项目的规范”。Leyden项目最初的目标是在Java语言规范中增加原生可执行文件,比如GraalVM原生镜像AOT编译器产生的可执行文件。在2020年6月正式创建后,该项目在两年内没有任何公开活动。
在2022年5月,Leyden项目再次出现并带来了第二个目标:对于在带有JIT编译器的JRE上运行的Java应用,为它们识别和实现广泛的优化。它之所以这样做,是因为GraalVM AOT编译器有一个强制的封闭性假设,也就是在构建时必须具有应用的所有信息,比如它的类和资源。有些Java应用和库使用了Java中的动态特性,这些特性在该限制下无法正常运行。第二个目标的一些优化需要对Java语言规范进行一些修改。它的实现将依赖于现有的工具,比如Hotspot VM和jlink工具。
2022年10月,Leyden项目详细介绍了如何实现这两个目标。它引入了在编译时和运行时之间运行的condenser的概念。它能够“将程序转变为一个新的、更快的、可能更小的程序,同时保留原程序的含义”。Java语言规范将进行改进,以包含condenser。
Condenser将会定义AOT编译和原生可执行文件如何适应Java,以实现Leyen项目最初的目标。但是condenser还会改善在带有JIT编译器的JRE中运行的Java应用,以服务于第二个目标。GraalVM Java编译器、JRE和HotSpot JIT编译器将继续获得独立于Leyden项目的特性和升级。所以,condenser提供了一个额外的优化层。
截止2022年12月份,condenser的开发尚未开始。这使得Leyden不太可能在2023年9月份发布的下一个Java LTS版本中交付condenser。所以,有Leyden项目成果的最早的Java LTS版本可能是2025年9月的Java 25。
Spring Boot刚刚在2022年11月发布了3.0版本,Spring Boot加入了在生产环境中支持GraalVM原生镜像AOT编译的Java框架大家庭,其他框架还包括Quarkus、Micronaut和Helidon。InfoQ就甲骨文的公告采访了这四个框架的代表。
第一个回应来自Red Hat Java团队的卓越工程师Andrew Dinn,以及Red Hat的首席软件工程师Dan Heidinga。2022年5月他们在InfoQ发表过文章,主张OpenJDK和GraalVM之间要更加紧密地结合。
InfoQ:你们在2022年5月份的文章中提到,“原生Java需要纳入到OpenJDK中,以实现与其他正在进行中的功能增强的共同演进”。从这个角度来讲,你们是如何看待甲骨文的声明的?
Andrew Dinn & Dan Heidinga:我们对甲骨文的声明和Leyden项目最近的进展都持非常乐观的态度。将GraalVM的关键部分,即JIT编译器和原生镜像,纳入OpenJDK项目,有助于将它们的开发和用户社区更好地结合在一起。
在OpenJDK项目下,采用共同的开发模型以及现有的OpenJDK管理方式,能够让GraalVM开发人员与更广泛的OpenJDK社区进行更好的沟通和协作。而且,这能够让这些组件更容易地影响其他Java项目的设计,如Valhalla或Amber,使它们更适应AOT编译。
最后,它将GraalVM直接纳入Java规范流程的管理之下,并确保Java和GraalVM在相同的方向上共同发展。
InfoQ:甲骨文还宣布,GraalVM原生镜像AOT编译器将会实现OpenJDK中Leyden项目的规范。Leyden最近推迟了原生Java的标准化,而选择了优化JIT编译。鉴于新的进展,你们如何看待这个决策?
Dinn & Heidinga:Leyden项目最近提出了针对Mark Reinhold关于如何解决这个问题的设想。他建议使用Condenser,将计算从应用的一个阶段转移至另外一个阶段。同时,他还提出了支持该方式所需的规范变更(为了提供一个稳定的基础,这是必要的任务)和Java语言的变更,比如惰性静态JEP草案。
这些都没有提及“延迟AOT”或“优化JIT”。这种方式使AOT和JIT,甚至通常的执行方式,都会得到优化。他的样例使用的是一个XML库,在运行时读取配置文件。这种转移计算的方式对AOT和JIT都有益。正如我们在像Quarkus这样的框架中看到的,在构建时初始化状态对快速启动至关重要。Leyden现在正在奠定基础,在保留程序含义的基础上进行预初始化,这是我和Andrew在文章中提出的关键需求之一。
这不仅仅是确保GraalVM与Java规范之间紧密且可靠地协作的问题。Mark的提案明确指出,Leyden项目如果需要的话,也需要谨慎而连贯地更新规范,以允许特定Condensation步骤的行为变化。例如,它甚至提到当面向完全封闭的AOT程序时,需要明确类加载器行为的语义。
将GraalVM纳入OpenJDK也会使来自这两个项目的代码混合和匹配更容易。也许,GraalVM的原生镜像AOT编译器会成为程序转换流水线中的最后condenser。
InfoQ:你们的文章中描述了在原生Java中无法使用的Java特性。对可观测性至关重要的Java Agent的支持是另一个缺失的特性。对于这些限制,GraalVM应该怎么做呢?
Dinn & Heidinga:GraalVM团队可能在未来一年左右的时间内忙于将他们的代码迁移至OpenJDK。项目的迁移往往会比预期地更长,即便他们提前有所预期也在所难免。
我们看到GraalVM社区正在致力于增加可用于原生镜像的工具,包括Red Hat为支持JFR和JMX所做的努力,以及在调试支持方面的工作,包括Red Hat和IntelliJ的努力,所有这些都是与甲骨文的开发人员一起进行的。
GraalVM处在一个很好的位置,可以继续演进并与现有的代理供应商合作,为原生镜像寻找合适的插装(instrumentation) API。在这个过程中,学到的所有内容都能直接用于Leyden,并加速Leyden的交付。
这就是现在的终极目标:将所有的经验和学习到的东西(希望还会有些代码)输入到Leyden的开发过程中,以帮助该项目交付所需的规范更新、语言变更和condenser工具,以推进整个框架、库和应用的广泛采用。
Sébastien Deleuze是来自VMware的Spring框架提交者,分享了Spring生态系统的观点。
InfoQ:你们如何看待Java的GraalVM JIT和AOT编译器转移至OpenJDK这一事件的?
Sébastien Deleuze:从将Spring应用编译成原生可执行文件开始,我们就与GraalVM团队进行了非常紧密的合作。我们的目标是限制“原生Java”和“JVM上的Java”之间的差异,同时保持AOT方式所带来的效率收益。所以,从我们的角度来看,GraalVM JIT和AOT编译器转移到OpenJDK是个好消息,因为这是在OpenJDK的旗帜下实现更统一的Java的关键一步,即便在原生Java和JVM之间还存在一些差异。
我们也到了这样一个节点,那就是越来越多的问题或优化需要OpenJDK代码库进行一些变更。所以,希望GraalVM在OpenJDK方面能够获得一些帮助,包括与Leyden项目更紧密的合作。
一直以来,GraalVM都是一个包含多个子项目的伞状项目,比如多语言(polyglot)技术,有着不同的成熟度和不同的适用场景。将转移到OpenJDK内容与其他内容区分开来,有助于更加专注于GraalVM原生镜像的支持,并明确GraalVM对终端用户的意义。
InfoQ:目前,GraalVM的Java编译器每年有四个特性版本,未来将有两个。这对Spring有什么影响吗?
Deleuze:的确,在我们试验Spring Native项目的时候,每年四个特性版本对于快速推进工作是相当有用的。但是,2022年11月底我们发布了Spring Boot 3,从此开始了对GraalVM原生的正式和生产级别的支持。因此,从这个角度看,GraalVM的特性发布节奏变慢并与OpenJDK的发布保持同步,将有助于一致地处理这些升级,减少出现频繁破坏性变更的风险,并且能够让我们有更多的时间从事长远的新特性。不要忘了,可以预测的是每年还会有四个季度性的关键补丁更新,以修补原生镜像支持方面的问题。
InfoQ:GraalVM Java编译器的开发将会有所不同,至少会有一个OpenJDK项目,另外还涉及提交者、审校者和JEP,这对Spring会有什么影响吗?
Deleuze:尽管流程会有所变化,但我们希望能够继续保持Spring与OpenJDK方面GraalVM团队的合作。同时,正如之前宣布的,我们与BellSoft(OpenJDK的主要贡献者之一)在JDK和原生支持方面保持着密切合作。在未来的几个月内,我们会分享关于该影响的更多细节。
Red Hat的卓越工程师和主管Jason Greene代表Quarkus框架做出了回应。
InfoQ:你们如何看待Java的GraalVM JIT和AOT编译器转移至OpenJDK这一事件的?
Jason Greene:我们认为这对GraalVM和OpenJDK社区都是一个积极的变化。这两个项目更紧密地联系在一起,将会增加双方的合作和代码共享,包括推进Leyden项目的工作。我们与这两个团队都有良好的关系,并期待着在新的结构中继续保持这种关系。
InfoQ: 目前,GraalVM的Java编译器每年有四个特性版本,未来将有两个。这对Quarkus有什么影响吗?
Greene: 这种变化可能意味着需要等待更长的时间才能在GraalVM的正式版本中出现原生镜像相关的新特性。但是,GraalVM也有一个扩展性的SPI,我们目前在Quarkus中使用了他。它与Quarkus本身相关的改善相结合,能够在频繁的Quarkus发布计划中改进Quarkus GraalVM原生镜像的体验。
InfoQ:GraalVM Java编译器的开发将会有所不同,至少会有一个OpenJDK项目,另外还涉及提交者、审校者和JEP,这对Quarkus会有什么影响吗?
Greene:我们预计这些变化对Quarkus社区的影响很小。即使OpenJDK的流程和工具有一些差异,但它们与当前的模式有着相似的目标。虽然GraalVM没有使用JEP,但是它们有关于issue相关的设计讨论,并且具有包含代码审查的PR过程。
甲骨文的架构师Graeme Rocher提供了来自Micronaut框架的观点。
InfoQ:你们如何看待Java的GraalVM JIT和AOT编译器转移至OpenJDK这一事件的?
Graeme Rocher:对于社区和GraalVM的广泛采用来讲,这是非常好的一个举措。
InfoQ:目前,GraalVM的Java编译器每年有四个特性版本,未来将有两个。这对Micronaut有什么影响吗?
Rocher:在GraalVM的早期采用阶段,每季度一次的发布节奏很有帮助。现在GraalVM已经很成熟和稳定了,所以在这个阶段,转为每年发布两个版本已经没有什么问题了,这更像是一件好事。Micronaut团队和GraalVM团队都在Oracle Labs工作,并将继续合作,确保每次发布的开发者构建和快照版本都经过良好的测试。
InfoQ:GraalVM Java编译器的开发将会有所不同,至少会有一个OpenJDK项目,另外还涉及提交者、审校者和JEP,这对Micronaut会有什么影响吗?
Rocher:毫无疑问,这会努力使AOT的众多API和注解实现标准化,随着这些新API的出现,我们会转而使用它们。然而,这对Micronaut来说并不是一个新的挑战,因为它已经与GraalVM同步发展,并在它们出现时适配了这些改进。
甲骨文的架构师Tomas Langer代表Helidon框架做出了回应。
InfoQ:你们如何看待Java的GraalVM JIT和AOT编译器转移至OpenJDK这一事件的?
Tomas Langer:JIT编译器会对运行时提供帮助,对Helidon的源代码和开发过程没有影响。对OpenJDK的任何性能改进都是非常棒的!
AOT编译会影响我们设计(和测试软件的方法)。如果原生镜像成为OpenJDK的一部分,那么与AOT相关工作的复杂性都会降低,我们只需要安装一个JDK即可。对于我们的客户来讲也是如此。
InfoQ:目前,GraalVM的Java编译器每年有四个特性版本,未来将有两个。这对Helidon有什么影响吗?
Langer:随着GraalVM原生镜像变得越来越成熟,我们应该不会看到像过去那样的重大变化。减少发布版本实际上会使我们更加轻松,因为我们应该比以往更容易支持最新的版本,实际上,我们正在跳过对GraalVM一些发布版本的支持,因为大量的测试和相关工作使我们难以保持对最新版本的支持。
InfoQ:GraalVM Java编译器的开发将会有所不同,至少会有一个OpenJDK项目,另外还涉及提交者、审校者和JEP,这对Helidon会有什么影响吗?
Langer:我想答案和前面的很相似,GralVM原生镜像越成熟,我们应该越容易使用它。
目前,GraalVM计划在2023年发布四个特性版本。至少第一个版本仍将包含GraalVM的Java编译器,因为GraalVM原生镜像将在2023年1月24日发布的23.0版本中获得对Java 19的完整支持。现在,还不清楚GraalVM的Java编译器何时会在GraalVM中进行最后一次发布,何时会在OpenJDK中进行第一次发布。
Karsten Silz在欧洲和美国作为全栈Java开发者(Spring Boot、Angular、Flutter)工作了23年。2004年,他在美国共同创办了一家软件产品创业公司。Karsten领导了13年的产品开发,在公司成功出售后离任。自2003年以来,他也曾作为承包商工作。2020年,他作为首席技术官在英国共同创立了SaaS初创公司“Your Home in Good Hands”。
查看英文原文:GraalVM Java Compilers Join OpenJDK in 2023, Align with OpenJDK Releases and Processes