- GraalVM 发布日历
- 适用于 JDK 24 的 GraalVM
- 适用于 JDK 23 的 GraalVM
- 适用于 JDK 22 的 GraalVM
- 适用于 JDK 21 的 GraalVM
- 适用于 JDK 20 的 GraalVM
- 适用于 JDK 17 的 GraalVM
- GraalVM 22.3.x
- GraalVM 22.2.x
- GraalVM 22.1.x
- GraalVM 22.0.x
- GraalVM 21.3.x
- GraalVM 21.2.x
- GraalVM 21.1.x
- GraalVM 21.0.x
- GraalVM 20.3.x
- GraalVM 20.2.x
- GraalVM 20.1.x
- GraalVM 20.0.x
- GraalVM 19.3.x
21.2.0.1
(2021-08-04)
这是针对 GraalVM 21.2.x 分支的热修复版本。它包含了一些操作性修复,例如
- 修复了基于 Java 11 的 GraalVM 中
StringBuilder
优化问题,以改进特殊字符解析(参见 #3627)。 (仅在 GraalVM Enterprise 中可用。) - 修复了在较旧的
glibc
上作为宏编译的date
C 扩展中使用的strspn
问题,导致在较新的glibc
上缺少__strspn_c1
符号(参见 #2406)。
21.2.0
(2021-07-20)
- Java 和编译器更新
- 平台更新
- Native Image
- 多语言运行时
- Truffle 上的 Java
- JavaScript
- WebAssembly
- LLVM 运行时
- Ruby
- Python
- R
- 工具
- 多语言嵌入
- Truffle 语言和工具实现
Java 和编译器更新
- 构建 GraalVM Community Edition 所基于的 OpenJDK 版本已更新至
- 基于 Java 8 的 GraalVM Community 为 8u302。参见 OpenJDK 8u302 Updates
- 基于 Java 11 的 GraalVM Community 为 11.0.12。参见 OpenJDK 11.0.12 Updates
- 基于 Java 16 的 GraalVM Community 为 16.0.2。参见 OpenJDK 16.0.2 Updates
- 构建 GraalVM Enterprise Edition 所基于的 Oracle JDK 版本已更新至
- 基于 Java 8 的 GraalVM Enterprise 为 8u301。参见 Java SE 8 release notes
- 基于 Java 11 的 GraalVM Enterprise 为 11.0.12。参见 Java SE 11 release notes
- 基于 Java 16 的 GraalVM Enterprise 为 16.0.2。参见 Java SE 16 release notes
- 改进了计数循环的循环限制分析。编译器现在将通过考虑之前的条件来检测和优化归纳变量的范围。当循环被计数时,它将适用于高级优化,如部分展开、反转和向量化。在此阅读更多信息:此处。(仅在 GraalVM Enterprise 中可用。)
- 为顺序代码新增了新颖的 SIMD(单指令多数据)向量化优化。此优化默认禁用,直到 21.3 版本。通过
-Dgraal.VectorizeSIMD=true
启用。(仅在 GraalVM Enterprise 中可用。) - 为非计数循环新增了新颖的 Strip Mining 优化。Strip Mining 默认禁用。通过
-Dgraal.StripMineNonCountedLoops=true
选项启用。(仅在 GraalVM Enterprise 中可用。) - 现有的
StringBuilderOptimizationPhase
对StringBuilder
模式执行高级转换,以直接构建最终的String
并消除不必要的中间String
和StringBuilder
。此版本通过添加对 JDK 中使用的紧凑String
表示的支持,增加了对 JDK11 中此优化的支持。核心优化得到了改进,以处理更多的代码形状并进行更多的常量折叠。(仅在 GraalVM Enterprise 中可用。) - 改进了长计数循环中的安全点消除。编译器现在可以在具有
long
归纳变量(而不是int
)的循环中消除安全点,如果它能静态地证明归纳变量的范围(即最大迭代次数)是Integer.MAX_VALUE - Integer.MIN_VALUE
,而之前它只会考虑int
类型的归纳变量。在此阅读更多信息:此处。(仅在 GraalVM Enterprise 中可用。) - 新增了一个名为“写下沉(Write Sinking)”的优化,试图将写入操作移出循环。写下沉是一项实验性功能,默认禁用。通过
-Dgraal.OptWriteMotion=true
启用。(仅在 GraalVM Enterprise 中可用。) - 实现了推测性守卫移动(Speculative Guard Movement)优化,试图将循环不变的守卫(例如,数组边界检查)从循环内部移到循环外部。此更改使 GraalVM Community 在 SpecJVM2008 上的几何平均吞吐量分数提高了 4.2%。在 Renaissance、DaCapo 和 ScalaDacapo 基准测试上的分数也增加了约 0.5%。通过
-Dgraal.SpeculativeGuardMovement=false
禁用。 - 为
Reference.refersTo
和PhantomReference.refersTo
添加了内部函数,就像 为 C2 所做的那样。 - 增加了对
do
/while
循环应用计数循环优化的支持,其首次迭代不受循环条件保护。 - 新增了守卫提升循环复制阶段,这应有助于提前编译流程 (GraalVM Native Image)。它将某些循环拆分为“快速”和“慢速”版本。如果在运行时已知不会发生异常,则选择快速循环。快速循环允许更多的循环优化和循环向量化。循环复制需要配置文件引导优化数据。通过
-H:-GuardHoistingLoopDuplication
禁用。 - 改进了 Graal 编译器,允许编译包含超过 64 个循环的提前方法。这解决了阻止 Native Image 编译方法体内超过 64 个循环的程序的问题。这是在生成的 Java 代码中常见的一种模式,例如由 ANTLR 等工具输出的代码。
平台更新
- Linux AArch64:GraalVM 针对 AArch64 CPU 架构的发行版在 21.2 中作为受支持版本发布,并启用了更多功能,例如 Ruby 运行时和 Java on Truffle (Espresso)。
- Java 16 支持:在此版本中,基于 Oracle JDK 16 或 OpenJDK 16 构建的 GraalVM 仍然是实验性的,但通过克服一些已知限制并添加对 Ruby、Python 和 WebAssembly 运行时的支持,已变得更加“成熟”。
Native Image
- 发布了用于 Native Image 的新的官方 Gradle 和 Maven 插件,并初步支持 JUnit 5 测试。这些插件将使 Java 应用程序作为原生可执行文件构建、测试和运行变得更加容易,并且原生 JUnit 支持允许 JVM 库通过 GraalVM Native Image 运行其测试套件。有关更多详细信息,请阅读公告博文。
- 在 JDK 11 上添加了基本的 Java Flight Recorder (JFR) 支持。此功能是 Oracle 和 Red Hat 合作开发的。使用
-H:+AllowVMInspection
构建的 Native Image 支持用 Java 编写的 JFR 事件(参见jdk.jfr.Event
)。要在运行时记录 JFR 事件,必须启用 JFR 支持和 JFR 记录。请查看文档或查看-XX:+FlightRecorder
和-XX:StartFlightRecording
选项的帮助信息。目前,JFR 支持仍然受到显著限制,即大多数 VM 内部事件以及大多数高级功能(如堆栈跟踪或内存泄漏检测)仍然缺失。 - 改进了资源处理:存储在镜像中的资源可以通过虚拟文件系统访问。
- 实现了类的预定义:为了在运行时支持
ClassLoader.loadClass
,需要在运行时加载的类可以提供给静态分析,以便它们包含在封闭世界分析中。这提高了与依赖动态类加载的库的兼容性,只要在运行时加载或生成的类是稳定的。此功能是与 Oracle 和阿里巴巴合作开发的。 - 从镜像中移除了不必要的安全提供程序:可访问的安全提供程序由静态分析自动检测。我们修复了一些错误,这些错误在某些情况下导致过多的提供程序可访问,从而导致镜像大小过大且不确定。现在也可以使用
-H:-EnableSecurityServicesFeature
完全禁用自动检测。 - 新增了“epsilon”GC,用于构建不带任何垃圾回收器的镜像,适用于只分配少量内存的极短运行应用程序。当分配的内存超过最大堆大小时,应用程序将失败。在镜像构建时使用
--gc=epsilon
启用。 - 更改了
--initialize-at-build-time
选项的行为,使其仅与参数一起使用。这可以防止用户编写不可组合的代码,并避免意外的语义错误。
多语言运行时
- 新增了默认启用的编译排队启发式算法。新的启发式算法在许多工作负载上改善了多语言运行时的预热时间。它检测当前正在执行的代码并优先编译此类代码。新的队列实现还使用动态编译阈值,根据编译队列的负载增加和减少编译阈值。新的启发式算法可以使用
--engine.TraversingCompilationQueue=true|false
启用或禁用。关于新启发式算法的更详细描述可以在此处找到。 - VM 检查现在在所有启动器中默认启用。不再需要重新构建语言启动器镜像以启用检查。现在可以使用
SIGQUIT
信号在执行过程中的任何点打印线程转储。通过在 GraalVM Enterprise 中使用--vm.XX:+UsePerfData
选项额外启用性能计数器,VisualVM 能够附加并监控使用native-image
运行的语言启动器。
Truffle 上的 Java
- 引入了 Truffle on Java HotSwap 插件 API,它允许重新加载代码而无需重新启动正在运行的应用程序。它旨在供框架开发人员反映对注解、框架特定更新(如已实现的服务或 bean)的更改。有关更多详细信息,请查看文档。
- 改进了字节码分派,使解释器速度提高了 15-30%。
- 新增了静态对象模型实现,可在运行时动态生成宿主类。目前尚处于实验阶段。
- 添加了修复程序,以防止外部线程进入 Espresso 并调用本机代码时发生崩溃。
- 修复了在较旧版本 GNU libc (<= 2.17) 上运行时崩溃的问题。
- 增加了对实现
Map
、Map.Entry
、List
、Iterator
或Iterable
的访客对象的额外互操作性消息的支持。
JavaScript
- 当不支持运行时编译时,GraalVM JavaScript 现在会打印警告。此警告可以通过
-engine.WarnInterpreterOnly=false
选项或-Dpolyglot.engine.WarnInterpreterOnly=false
系统属性禁用。 - 新增了
js.unhandled-rejections
选项,用于跟踪多语言Context
中未处理的 Promise 拒绝。默认情况下,该选项设置为none
,不跟踪未处理的 Promise 拒绝。 - 实现了 新 Set 方法提案。它可通过实验性标志 (
--js.new-set-methods
) 启用。 - 实现了实验性运算符重载支持。使用实验性选项
--js.operator-overloading
启用它并查阅文档。 - 更新了带有
d
标志的 RegExp 匹配索引提案,支持选择启用。在 ECMAScript 2022 (-js.ecmascript-version=2022
) 中可用。-js.regexp-match-indices
选项已弃用。
更新日志在项目仓库中提供。
WebAssembly
- GraalVM 的 WebAssembly 现在可以正确检测内存分配失败,并根据规范抛出 WebAssembly 错误(
RangeError
异常),而不是返回内部引擎错误。 - 修复了从导入表中调用函数的边缘情况。在间接调用(
call_indirect
指令)中,当函数从不同模块导出并设置为导入表中的条目时,GraalWasm 现在将正确地进行函数类型检查。 - 改进了某些算术错误的检测,打印出更具体的算术异常类型。在早期版本中,处理某些算术错误会导致
NullPointerException
。 - 进行了通用维护工作并修复了错误,以尽可能多地通过使用 WebAssembly 的 NPM 模块的测试。
LLVM 运行时
- 增加了对
pthreads
和pthread
同步原语在托管模式下的支持,例如pthread_create
、pthread_exit
、pthread_join
、pthread_mutex
、pthread_rwlock
、pthread_cond
等。这使用户能够运行多线程程序。以前,当用户尝试运行多线程软件时,它会失败。(仅在 GraalVM Enterprise 中可用。) - 更新
musl libc
至版本 1.2.2。(仅在 GraalVM Enterprise 中可用。) - 增加了通过跨语言互操作性支持 C++ 虚调用。
- 增加了对现有汇编指令的原子版本支持。这意味着 LLVM 运行时现在对内联汇编有更广泛的支持,特别是对于多线程软件。
- 修复了 GraalVM 的 LLVM 工具链在 MacOS 11.3 上无法正确用于 C++ 的问题(参见 #3383)。
项目更新日志可在 GitHub 上查阅。
Ruby
- 通过使用按名称和按类假设,实现了 Ruby 方法和常量的精确失效。
- 更新至 Ruby 2.7.3(修复了 CVE-2021-28965 和 CVE-2021-28966)。
resolv
stdlib 未更新(2.7.3 中的resolv
存在错误)。 - 修复了 macOS 10.13 上的 LLVM 工具链问题(参见 #3383)。
- 改进了
#dig
方法,使数组和哈希的迭代更快,并更好地编译具有 3 个以上参数的调用(参见 #2301)。 - 通过减少同步改进了纤程局部变量,使其速度更快。
- 现在使用
TruffleSafepoint
而不是自定义逻辑,这不再使访客安全点(例如Thread#{backtrace,raise,kill}
,ObjectSpace
等)的 JIT 编译代码失效。
完整的更改列表可在更新日志中找到。
Python
- 实现了
_pickle
,其速度比纯 Python 版本更快。用户在通过网络序列化对象时将看到更好的性能。(仅在 GraalVM Enterprise 中可用。) - 通过添加快速路径、内部化函数以及为常见数据结构添加优化表示,改进了 Python 性能,尤其是在预热和共享引擎配置中。
- 应用了新的 Truffle 安全点机制,以实现更高效的 GIL 释放、信号处理程序和弱引用回调。
- 支持的 HPy 版本更新至 0.0.2。
- 增加了对
dict
类型通过新哈希互操作性消息正确使用的支持。现在 Python 字典可以转换为java.util.Map
,在使用 Java 调用 Python 时表现符合预期。 - GraalVM Python 运行时现在通过了更多
io
、crypt
以及socket
、OrderedDict
和time
中更多函数的兼容性测试。使用这些功能的 Python 3.8 代码现在有望更好地工作。 - 增加了对
psutil
包的初步支持,该包支持系统访问和进程监控,以及用于编写视频游戏的PyGame
模块。 - 如果当前工作目录中存在文件名“sitecustomize.py”,GraalVM 的 Python 不再无条件创建
_pycache_
。
更多详细信息可在更新日志中找到。
R
- 继续改进与 R 4.0.3 的兼容性。例如,对
rlang
0.4.10、vctrs
3.6、tibble
3.0.6 和testthat
3.0.1 包的支持得到了显著改进。 - 已知存在问题的包
dplyr
1.0.3、ggplot
3.3.3 和knitr
1.31 仍然存在。
更多详细信息可在项目更新日志中找到。
工具
Visual Studio Code
- VS Code 扩展重命名如下
- GraalVM Tools for Java
- GraalVM Extension Pack for Java
- GraalVM Tools for Micronaut
GraalVM Tools for Java 扩展
- 实现了对 JDK16 及其语言功能的完全支持。
- 添加了对开发、运行和调试单个 Java 类的支持,支持 JDK8 及更高版本。
-
引入了向导,可轻松创建新的 Java 项目:
-
引入了新的类向导“Java: New From Template”,允许向项目添加各种 Java 及相关文件:
-
实现了将调试器附加到正在运行的进程的可能性。可通过运行和调试“Java 8+…”配置使用。
- 通过“转到类型”和“查找用法”选项改进了 Java 代码导航。
- 在“无调试器运行”模式下启用了 Native Image 代理收集配置数据。这使得从 VS Code 构建原生镜像更加容易。使用特殊的启动配置 启动带有 Native Image 代理的 Java 8+ 应用程序。
GraalVM Tools for Micronaut 扩展
- 新增了“启动 Java: 持续模式”启动配置,也称为 Gradle 和 Maven 项目的“运行开发模式”:
- 开发并运行了 Groovy 语言的 Spock 测试。包括 Groovy 的代码补全和其他编辑支持。
VisualVM 和 VS Code 集成
- 在 VS Code Gr 活动中添加了特殊部分,用于控制活动 GraalVM 安装中包含的 VisualVM 工具。主要更新包括
- 支持与 VS Code 项目一起启动 VisualVM
- 提供了获取线程或堆转储的操作,以及配置和控制 CPU/内存采样和 JFR 记录的操作
- 在 VisualVM 视图中启用了“转到源”操作,该操作将源重新打开到 VS Code 中
VisualVM
- 新增了从实时进程保存 JFR 记录的功能(参见 #297)。
- 通过在 Profiler 选项卡中添加锁竞争视图,实现了锁竞争分析功能(参见 #298)。
- 增加了对 JDK 17 的支持。
- 支持从命令行或外部工具控制 VisualVM 实例:启动采样(#321),控制飞行记录(#322),从终端获取 Java 进程的线程(#319)或堆转储(#320)。
- 发布了 VisualVM 的 Maven 工件。
多语言嵌入
正如在 21.1 发布说明中宣布的那样,此版本中我们更新了多语言嵌入所需的 JVMCI 版本。所有 GraalVM JDK 版本(8、11、16)均已包含更新后的 JVMCI 版本,无需进一步操作。如果您使用的 JDK 不是 GraalVM 且您已在升级模块路径上配置了 Graal 编译器,则需要包含 JDK-8264016 的以下 JDK 版本之一,以实现完全兼容性
- 其他 JDK 11:Oracle JDK 11.0.13 (2021-10-19),OpenJDK 待定。
- 其他 JDK 16:目前没有更新 JVMCI 的计划。
- 其他 JDK 17:新的 JVMCI 版本已集成到早期访问构建中。
如果您的 JVMCI 版本过时,您仍然可以使用 GraalVM 嵌入,但强制上下文取消 (Context.close(true)
) 和中断 (Context.interrupt(Duration)
) 将抛出错误。我们建议以下变通方法
- 不要使用强制上下文取消或中断。所有其他功能仍然支持。
- 通过从 upgrade-module-path 中移除 graal.jar 来切换到回退运行时。请注意,这会显著降低性能,应仅作为最后手段。
- 等待 JDK 版本支持新的 JVMCI 版本后再升级到 21.2。
其他更改
- 更改了
Value.as(TypeLiteral<Function<Object, Object>>).apply()
的行为:当函数使用Object[]
参数调用时,它作为单个参数而不是参数数组传递(参见 #456)。
完整的更改列表可在此处找到。
Truffle 语言和工具实现
- 增加了对 Truffle 库的支持,以便在不预先执行的情况下进行提前编译。有关更多详细信息,请参见 ExportLibrary.useForAOT 或 AOT 教程。
- 实现了
DebugValue
方法hashCode()
和equals()
,分别提供对应访客对象上的互操作性identityHashCode
和 isIdentical 调用的结果。 - 向
DebugValue
添加了对迭代器和哈希映射的支持。添加的方法委托给InteropLibrary
的相应方法。 - Truffle 专用化 DSL 中使用
@Fallback
注解的方法现在支持@Cached
、@CachedContext
、@CachedLanguage
、@Bind
和分派的@CachedLibrary
参数。 - 新增
TruffleContext.pause()
和TruffleContext.resume(Future<Void>)
,分别用于暂停和恢复 Truffle 上下文的执行。 - 新增
CompilerDirectives.blackhole(value)
,这有助于基准测试。 - 新增
TruffleLanguage#Env.registerOnDispose(Closeable)
,注册一个Closeable
以便在上下文释放时自动关闭。 - 新增
RootNode#countsTowardsStackTraceLimit()
,取代RootNode#isInternal()
作为确定具有给定根节点的帧是否计入堆栈跟踪限制的标准。 - 新增
MemoryFence
,提供用于对内存排序进行细粒度控制的方法(参见 #2031)。 - 弃用
ValueProfile.createEqualityProfile()
,无替代。在编译代码路径上不能安全地使用Object.equals(Object)
。请改用 Truffle 专用化 DSL 来实现具有相等语义的缓存。在原生镜像中,将Object.equals(Object)
设置为运行时编译方法会标记过多 equals 实现可用于运行时编译。 - 弃用并添加了支持
ArityException
实例中预期参数范围的方法。请注意,替代方法现在包含更严格的验证。 - 如果
@Shared
和@Cached
参数返回非空值并用于守卫中,则专用化 DSL 现在生成代码以抛出AssertionError
。空状态保留用于未初始化状态。 - 新增
LoopConditionProfile#create()
作为createCountingProfile()
的别名,因此它可以像@Cached LoopConditionProfile loopProfile
一样使用。
完整的更改列表可在此处找到。