用于 JDK 17.0.9 的 GraalVM

(2023-10-24)

这是 GraalVM Community Edition 的 2023 年 10 月关键补丁更新 (CPU)。它基于 OpenJDK CPU,并包含了作为该 CPU 一部分发布的所有 OpenJDK 安全修复、平台更新以及一些 GraalVM 功能的错误修复。这是一个完整的发行版,取代了之前发布的用于 JDK 17.0.8 的 GraalVM Community Edition。

  • 用于 JDK 17 的 GraalVM Community Edition 已更新至 17.0.9+9。请参阅 OpenJDK 17 更新
  • 版本兼容性
  • 编译器修复
    • 修复了交替 Phi 被错误检测为归纳变量的问题。
    • 修复了 macOS AArch64 上的错误编译。
  • Native Image 修复
    • 将功能异常重新抛出为用户错误。
    • 为外部调用正确设置 exceptionTemp
    • RecordComponents 的访问器为 null 时忽略它们。
    • 改进了构建报告。
    • 不将非最终的 JDK 方法标注为不可中断。
    • 修复了采样器启动期间缓冲区池调整不正确的问题。
    • 使物理内存大小主动初始化。
    • 修复了 Netty 5 中“静态分析后发现新的 VarHandle”的问题。
  • Truffle 框架修复
    • 修复了在 JIT 模式下使用隔离区并共享引擎时,如果上下文未关闭导致的 NullPointerException
    • BigInteger 值创建的已断开连接的 polyglot.Value 实例对于 isNumber() 不应默认返回 false。
    • 修复了 AbstractTruffleString.equals() 方法中的 NullPointerException
    • 修复了 PolyglotStackFramesRetriever 中的死锁。
    • 在 MPK 支持完成之前,禁止不受信任代码的硬件缓解措施。

用于 JDK 17.0.8 的 GraalVM

(2023-07-25)

这是 GraalVM Community Edition 的 2023 年 7 月关键补丁更新 (CPU)。它基于 OpenJDK CPU,并包含了作为该 CPU 一部分发布的所有 OpenJDK 安全修复、平台更新以及一些 GraalVM 功能的错误修复。这是一个完整的发行版,取代了之前发布的用于 JDK 17.0.7 的 GraalVM Community Edition。

  • GraalVM Community Edition 构建所基于的 OpenJDK 版本已更新至 17.0.8+7。请参阅 OpenJDK 17 更新
  • Graal 编译器:更新了计数带状开采优化,使其不对溢出循环进行带状开采。
  • Native Image:修复了 jvmstat 性能数据初始化问题。
  • Native Image:修复了 JDK Flight Recorder (JFR) 事件常量池 ID 问题。
  • Native Image:修复了 Native Image 中的用户体验问题。
  • Native Image:修复了构建报告中的分析结果问题。

用于 JDK 17.0.7 的 GraalVM

(2023-06-13)

平台更新

  • 发布了基于 OpenJDK 17.0.7+8 的 用于 JDK 17 的 GraalVM Community Edition。请参阅 OpenJDK 17 更新
  • 简化了 GraalVM 包命名:它现在是 graalvm-community-jdk-<full java version>_<platform>-<arch>,例如:graalvm-community-jdk-17.0.7_macos-aarch64_bin.tar.gz

Java 和编译器更新

  • 为需要低延迟或使用超大堆的工作负载添加了对 ZGC 垃圾收集器的支持。详见 #2149
  • 通过添加非推测模式,加强了乐观别名分析。(改进了循环向量化。)以前,某些代码形态仅在 JIT 中向量化,而不是在预先编译中进行。随着 Native Image 循环向量化的改进,这些代码形态的差异已消失,使编译器能够向量化更多循环以实现更快的执行。
  • 改进了新颖优化编译器阶段的日志记录:统一了记录和转储(例如,通过 JSON)优化决策的接口。优化阶段应使用 OptimizationLog 来记录转换。更多详情请参阅 OptimizationLog.mdProfdiff.md,了解如何在热编译中比较已执行的优化。
  • Ideal Graph Visualizer (IGV) 开源,以便第三方编译器和语言开发者更轻松地使用和贡献。更多详情请参阅 此处

更多更新请参阅更新日志

Native Image

打包和平台更新

  • Native Image 现在作为用于 JDK 17 的 GraalVM 的一部分提供,不再需要通过 gu install native-image 进行安装。更多详情请参阅 此处
  • 如果 Native Image 能够在已知位置找到 Visual Studio 安装,它现在会自动在 Windows 上设置构建环境。因此,不再需要运行 x64 Native Tools 命令提示符。
  • 改进了 Linux 上 AWT 库的动态链接。Linux 上 AWT 库的静态链接一直是个问题。动态链接避免了静态链接的缺陷,但代价是无法再拥有独立二进制文件,这是一种合理的权衡,如 Windows 上 AWT 支持所示。链接器不再会因为“jvm 的多重定义”而失败,也不会在 Linux 上为 AWS/Swing 应用程序的链接步骤中崩溃。
  • Jipher JCE,一个基于 OpenSSL 3.0 FIPS 实现的 Java 加密体系结构 (JCA) 提供程序,现在支持 GraalVM Native Image。建议在仅应使用 FIPS 允许算法的环境中,通过 Native Image 启用 Jipher。请参阅文档以开始使用。

新功能

  • 引入了一项新功能:按需从自包含的 bundle 构建原生可执行文件。新选项 --bundle-create=<imagename>.nib 会创建一个 <imagename>.nib 文件(构建包)和 launch.output 目录以及原生可执行文件。包文件 <imagename>.nib 是一个常规 JAR 文件,其中包含构建原生可执行文件(或原生共享库)所需的所有信息。与常规的 native-image 构建不同,此操作模式仅将单个 *.nib 文件作为输入。稍后,如果使用相同版本的 GraalVM,可执行文件可以通过以下方式重建:
    native-image --bundle-apply=.../path/to/launch.nib
    

    它将使用与初始构建相同的镜像参数、环境变量、系统属性、类路径和模块路径选项来重建原生可执行文件。这是一种安全可靠的解决方案,可将构建所需的所有输入封装到一个文件中。在 Native Image Bundles 参考手册中了解更多信息。

  • 改进了 Native Image 构建过程的内存占用。构建器现在会考虑可用内存,以在同一机器上运行许多其他进程时减少内存压力。它在许多情况下也消耗更少的内存,因此也更不可能因内存不足错误而失败。同时,内存限制已从 14GB 提高到 32GB。
  • Native Image 现在在 AMD64 上默认以 x86-64-v3 架构为目标,并提供一个新的 -march 选项来指定目标兼容性。如果原生可执行文件部署在同一台机器或具有相同 CPU 功能的机器上,请使用 -march=compatibility 以获得最佳兼容性,或使用 -march=native 以获得最佳性能。要列出所有可用的机器类型,请使用 -march=list
  • 通过抛出特殊异常,改进了 Native Image 中元数据缺失的报告。Native Image 不区分缺失的可达性元数据和由 Reflection API 抛出的异常。例如,当类不在类路径上或类元数据不存在时抛出的 ClassNotFoundException。现在,Native Image 用户可以捕获元数据异常,并使用选项 -XX:ExitOnMissingMetadata 调试其程序,以确保所有元数据条目都是正确的。更多详情请参阅 此处。这是一项实验性功能,默认未启用。
  • 在 Native Image 中引入了 Reflection 和 Resources 元数据的安全组合。例如,java.lang.Class#getDeclaredMethodsreturn 等反射方法基于其他反射元素的可达性。添加新的元数据会使更多元素可达,并可能改变程序功能。借助元数据优化的安全组合,native-image 构建器现在确保对 java.lang.Class 的每次反射调用都需要一个元数据条目。更多详情请参阅 此处
  • 禁止不带参数的 --initialize-at-build-time 选项。作为临时解决方案,-H:+AllowDeprecatedInitializeAllClassesAtBuildTime 选项将此错误转换为警告。
  • 通过 LLVM 后端为 Native Image 添加了实验性的 RISC-V 模式。在这篇博客文章中了解更多信息。
  • 改进了 Native Image 中的配置文件引导优化 (PGO)(PGO 在 GraalVM Community Edition 中不可用)
    • 配置文件引导优化具有一个新的采样分析器,可定期收集调用堆栈。使用选项 --pgo-sampling 开启采样分析器并收集调用堆栈。这些数据随后会包含在 .iprof 文件中。当构建 PGO 仪表化的可执行文件时,采样分析器默认开启(但可以通过选项 -H:-SamplingCollect 关闭)。为了获得良好的配置文件和最佳峰值性能,您需要运行相关工作负载并正确预热应用程序。
    • 实现了上下文感知内联器 (CAI) 优化,该优化专门处理“热”代码中的采样配置文件,并投入更多优化工作到热编译单元。当为 PGO 构建优化镜像时,上下文感知内联器会自动开启(但可以通过选项 -H:-AOTInliner 关闭)。结果是可执行文件大小减小 2-7%,峰值性能提高。
    • 改进了配置文件合并并启用了预打包配置文件。
  • 添加了基于机器学习 (ML) 的配置文件推断。当禁用性能分析时,Native Image 中的 Graal 编译器使用预训练的 ML 模型来推断控制分支的配置文件。然后,推断出的配置文件用于执行配置文件引导优化。在 Renaissance、Da Capo 和 Da Capo con Scala 等某些基准测试中,此优化相比默认的 Oracle GraalVM 配置提供了约 6% 的运行时加速。通过运行带有 ML 配置文件推断的原生可执行文件构建,您可以预期二进制文件大小会略微增加 1%-2%。此优化在 Oracle GraalVM 中默认启用(在 GraalVM Community Edition 中不可用)。要禁用它,请使用以下选项:-H:-MLProfileInference
  • Native Image SBOM 现在包含一个用于运行时组件的单一 SBOM 组件。该组件使用可执行文件的 java.vm.version 属性来标识版本,并属于新的 graalvm-native-image 产品。

构建输出改进

  • 构建器现在可以生成构建报告,帮助您更好地理解可执行文件的内容。使用 -H:+BuildReport 尝试此新的实验性功能。
  • 改进了内部错误报告,使其更用户友好。一条清晰的消息告诉用户如何操作:检查错误报告,如果无法解决问题,请附带错误报告提交问题。受 HotSpot 启发,错误报告的默认文件名为 ./svm_err_b_<timestamp>_pid<pid>.md。这还添加了一个新选项 -H:ErrorFile,允许您为错误报告选择不同的文件名。详见 #5414
  • 调整了 native-image 构建输出,以报告类型(基本类型、类、接口和数组)而非类,并修订了 -H:BuildOutputJSONFile 的输出模式。
  • native-image --version 命令的输出以及各种 Java 属性(例如 java.vm.version)与 OpenJDK 保持一致。要区分 GraalVM Community Edition、Oracle GraalVM 和其他供应商的 GraalVM 发行版,请参考 java.vm.vendor

调试和监控体验改进

  • 弃用了不带参数使用 --enable-monitoring 选项的做法。该选项不再默认设置为 all。相反,请始终明确指定要启用的监控功能列表,例如:--enable-monitoring=heapdump,jfr,jvmstat
  • 添加了选项 -XX:HeapDumpPath 来控制堆转储文件的创建位置。
  • 为应用程序监控添加了更多 JFR 事件:ExecutionSampleObjectAllocationInNewTLABJavaMonitorInflate
  • 改进了 Windows 上的调试:调试信息现在包含 Java 类型的信息。(与 Red Hat 合作。)
  • 实现了通过 JMX 对 Native Image 进行远程管理,可以通过选项 --enable-monitoring 启用,例如:--enable-monitoring=jmxclient,jmxserver。更多详情请参阅 此处。该功能是实验性的。(与 Red Hat 合作。)
  • 为 Native Image 启用了 JFR 事件流。该功能是实验性的。(与 Red Hat 合作。)

Native Image 更新日志中查找更多更新。

JavaScript 和 Node.js

  • 将 Node.js 更新到 18.14.1 版本。
  • 添加了 BigInteger 互操作性支持。请注意,外部 BigIntegers 需要使用 BigInt 函数进行显式类型转换,才能选择使用 JS BigInt 语义。默认语义是将所有外部数字视为 JavaScript Number 值,无论其原始值或类型如何。算术运算符执行隐式有损双精度转换。比较运算符在可能的情况下尝试进行精确的值比较。JavaScript BigInt 值现在可以转换为 java.math.BigInteger 主机对象,尽管如果目标类型不明确或缺失,可能仍需要目标类型映射以确保类型映射的一致性。
  • 在 GraalVM JavaScript 运行时中实现了多项新的 ECMAScript 提案

更多更新请参阅项目更新日志

多语言嵌入

  • 这是第一个支持在代码沙盒中运行不受信任应用程序的版本。沙盒策略 Context.Builder#sandbox(SandboxPolicy) 具有四种不同的沙盒级别:ISOLATEDUNTRUSTEDTRUSTEDCONSTRAINED,旨在使用户能够在主机应用程序和访客代码之间建立安全边界。该策略通过将其传递给 Engine.Builder#sandbox(SandboxPolicy)Context.Builder#sandbox(SandboxPolicy) 构建器方法来设置。例如,主机代码可以使用 UNTRUSTED 策略执行不受信任的访客代码。主机代码还可以执行多个相互不信任的访客代码实例,这些实例将相互保护。在多语言沙盒指南中了解更多信息。代码沙盒目前仅支持 JavaScript。SandboxPolicy.ISOLATEDSandboxPolicy.UNTRUSTED 策略在 GraalVM Community Edition 中不可用。
  • 与代码沙盒实现相关,新增了一个选项 TraceLimits,用于测量访客应用程序的资源消耗并获取实际的沙盒参数。
  • 添加了 IOAccess API:多语言上下文的 IO 访问配置。IO 访问配置决定了访客语言如何访问主机 IO。新的 IOAccess 类提供了一个预定义配置,用于禁用主机 IO 访问或启用完全主机 IO 访问。可以使用 IOAccess 构建器创建自定义配置。
  • java.lang.BigInteger 添加到 Polyglot Value API。默认情况下,所有类型为 java.lang.BigInteger 的主机值现在都被解释为数字值 (Value.isNumber()),这与之前不同。为了恢复旧行为,请将 HostAccess.Builder.allowBigIntegerNumberAccess(boolean) 设置为 false。请注意,对不适合长整型值的数字的语言支持可能有所不同。某些语言(如 JavaScript)可能需要显式转换主机大整数。其他语言(如 Ruby 或 Python)无需显式转换即可使用大整数。相同情况也适用于跨访客语言传递的值。详见 #2737
  • 添加了语言资源的自动复制功能,用于在 Native Image 中嵌入 Truffle 语言。文档可在此处获取。

完整的更改列表可在更新日志中获取。

Truffle 语言和工具实现

  • 为 Truffle DSL 实现了多项新功能以提高性能。特别是,引入了一个名为 @GenerateInline 的新注解,它允许 Truffle 节点自动进行对象内联。对象内联的 Truffle 节点成为单例,从而减少内存占用。这与 @GenerateCached@GenerateUncached 类似,它们生成缓存或未缓存的节点版本。请参阅文档以获取更多详细信息。

其他有助于性能改进的更新包括

  • 更新后的 Truffle DSL 节点在特化期间不再需要节点锁,从而提高了首次执行性能。现在使用 CAS 风格的内联缓存更新来避免在守卫中调用 CallTarget.call(...) 时发生死锁。内联缓存继续保证没有重复值,并且不受竞态条件的影响。语言实现者应注意,减少争用可能会揭示语言中的其他线程安全问题。
  • 通过合并生成的字段以表示状态、排除位集以及改进特化数据类生成以考虑激活概率,从而改进了 Truffle DSL 节点的内存占用。特化应按激活概率排序以获得最佳结果。
  • 通过将枚举类型的缓存参数值自动内联到状态位集中,改进了内存占用。
  • Truffle DSL 现在会针对建议发出更多警告。例如,它会在内联机会、缓存共享或缓存初始化器应指定为 @NeverDefault 时发出警告。为了简化迁移工作,增加了暂时为 Java 包抑制警告的新方法。有关可能警告的列表和更多使用说明,请参阅文档
  • 未关闭的多语言引擎在虚拟机关闭时不再自动关闭。它们随虚拟机一起终止。因此,在虚拟机关闭时,未关闭引擎上的活动工具不会调用 TruffleInstrument#onDispose。如果工具在处置前需要执行某些特定操作,例如打印某种摘要,则应在 TruffleInstrument#onFinalize 中完成。
  • 实现了控制代码沙盒限制的策略。默认情况下,语言和工具仅支持 TRUSTED 沙盒策略。
    • 如果语言想要针对更严格的沙盒策略,则必须
      • 使用 TruffleLanguage.Registration#sandbox() 指定其满足的最严格沙盒策略。
      • 对于每个选项,语言必须通过 Option#sandbox() 指定可以使用该选项的最严格沙盒策略。默认情况下,选项具有 TRUSTED 沙盒策略。
      • 如果语言需要额外的验证,可以使用 TruffleLanguage.Env#getSandboxPolicy() 获取当前上下文沙盒策略。
    • 如果工具想要针对更严格的沙盒策略,则必须
      • 使用 TruffleInstrument.Registration#sandbox() 指定其满足的最严格沙盒策略。
      • 对于每个选项,工具必须通过 Option#sandbox() 指定可以使用该选项的最严格沙盒策略。默认情况下,选项具有 TRUSTED 沙盒策略。
      • 如果工具需要额外的验证,可以使用 TruffleInstrument.Env#getSandboxPolicy() 获取引擎的沙盒策略。

Truffle 更新日志中查找更多更新。

Truffle 上的 Java (Espresso)

新功能

改进

  • 启用了通过互操作调用重载和可变参数方法。
  • 改进了与外部异常的互操作性。现在可以获取堆栈跟踪,并且可以使用类型映射来显式映射异常。

Python

性能改进

  • 添加了 Python C API 接口的新实现,默认使用完全原生执行。这提高了性能以及与某些在原生代码中花费大量时间的扩展(如 SciPy、PyTorch 等)的兼容性,但可能对频繁跨越 Python/原生边界的工作负载产生负面影响。有新的选项可以控制扩展的构建和运行方式:python.NativeModulespython.UseSystemToolchain。新的默认设置是使用主机系统的工具链来构建扩展,而不是 GraalVM 附带的 LLVM 工具链,并以原生方式运行所有模块。新的启动器 (graalpy-lt) 可用于获取旧行为,这对于调试可能很有用。
  • 我们在网站上报告的性能数据现在基于社区的pyperformance 基准测试套件的结果,测量 GraalPy 相对于 CPython 和 Jython 的几何平均加速。这使得比较和重现我们的结果变得更容易。

平台更新

  • 实现了在 Windows 上构建和运行基本的 GraalPy 工作负载。这使得 Windows 用户能够构建和使用 GraalPy,特别是用于嵌入到 Java 中。
  • Virtualenv 的 GraalPy 插件添加为内置模块,以便在 GraalPy 上使用 virtualenv 创建虚拟环境开箱即用。
  • 更新了内置的 venv 模块,以使用符号链接创建虚拟环境,而不是生成委托给基础 GraalPy 的 shell 脚本。

兼容性改进

  • 将语言版本和标准库更新到 3.10.8,使其与更多最新的模块和包兼容。
  • 更新了 GraalPy 的分发布局以匹配 CPython 的。这减少了各种构建系统发现 GraalPy 库位置所需的补丁数量。
  • 更新了 numpypandas 版本。
  • 使用 ginstall 实现了 scipyscikit_learn

完整的更新列表可在项目更新日志中找到。

Ruby

新功能

  • 已更新到 Ruby 3.1.3。
  • 现在支持外部大整数,并与所有 Numeric 运算符兼容。

性能

  • 使得 psych 可以使用系统 libyaml,这改进了解析 YAML 时的预热性能。这意味着 libyaml 现在是一个依赖项。参阅如何安装 LibYAML
  • 现在在 C 调用退出时完成对象中封装的原生结构的标记,以减少内存开销。
  • 通过实现 cloneUninitialized() 优化了调用目标的拆分(复制)。
  • Process.pid 现在像 $$ 一样按进程缓存。
  • 修复了在给定调用点上通过多次调用不断增长的构建 Array 方法的重复去优化问题。

错误修复

  • 修复了 macOS 上的 spawn(..., fd => fd),此前由于 macOS 错误而无法工作。
  • 修复了 rb_gc_register_address()/rb_global_variable() 以读取最新值(详见 #2721, #2734)。

完整的更改列表可在项目更新日志中找到。

LLVM

  • 将 LLVM 工具链更新到 15.0.6 版本。
  • musl libc 更新到 1.2.3 版本。
  • 在 Linux AArch64 架构上实现了 long double(128 位浮点)。

WebAssembly

  • 添加了对 DWARFv4 的实验性调试支持。这使得 C、C++ 和 Rust 应用程序的调试成为可能。
  • 添加了对 Memory64 的实验性支持。该功能可以通过选项 --wasm.Memory64=true 启用。
  • 实现了 Bulk-MemoryReference-Types 提案。它们可以通过选项 --wasm.BulkMemoryAndRefTypes 禁用。

联系我们