甲骨文实验室已经发布GraalVM 21.1,该版本具有针对Java 16的实验性二进制文件。这个新版本还包含了性能改进和一些新的功能,如支持Native Image中的多种语言。Node.js最初包含在以前版本的GraalVM安装包中,现在是一个需要手动安装的可选依赖项。
基于OpenJDK的GraalVM社区版二进制文件已更新至Java 8u292、11.0.11和16.0.1,基于Oracle JDK的GraalVM企业版二进制文件已更新至Java 8u291、11.0.11、16.0.1。
支持Java 16的两个版本可用于测试和评估,但仍在开发中。在生成本地图像时,JDK 16有三个已知问题。 unexpected method:proxyClassLookup
错误当使用 default proxy methods构建本地图像时发生; jdk.vm.ci.common.JVMCIError: Unknown JvmConstant tag 17
错误在类中的lambda表达式在运行时被初始化时发生,并且对JDK Flight Recorder(JFR)的支持不可用。其他几个工具,如VisualVM,已经兼容JDK 16。VisualVM现在与苹果的M1芯片兼容。
新版本的Visual Studio Code (VS) Extensions将单元测试结果可视化,并提供对Java代码重构的支持。在GraalVM 19.2中首次引入了各种功能,包括Micronaut VS Code Extension、对YAML和Docker构建的支持,以及对配置文件和Java代码的协助。
与GraalVM 19.0发布时的native-image
工具类似,Node.js已成为一个可选的依赖,需要手动安装,不再默认启用。它可以通过GraalVM更新工具gu
,调用gu install nodejs
命令来安装。因此,社区版download小了约50MB。JavaScript运行时间仍然包含在GraalVM的安装中。
基于OpenJDK 8的MacOS的GraalVM社区版构建已不再生产。Linux AArch64的构建仍然是实验性的,但包括GraalVM编译器、gu
工具、Node.js、Native Image和一些开发工具。
编译器被进一步优化,以消除x86处理器上连续易失性写入的不必要的内存障碍。当内联代码时,许多易失性写入可能依次发生。现在,编译器将放弃内存障碍,除了序列中的最后一次写入,这提高了方法的性能,如ConcurrentHashMap.transfer()
。
另一项优化是取消了对加载的数组元素进行转换的做法。当易失性字段从数组中加载并丢失元素的类型信息时,这是必要的。在下面的例子中,(Node<K,V>)
不再需要转换。
static final <K,V> Node<K,V> tabAt(Node<K,V>[] tab, int i) {
return (Node<K,V>)U.getObjectVolatile(tab, ((long)i << ASHIFT) + ABASE);
}
对地区性的支持也得到了改进,在一个Native Image中可以使用多种地区性。开发者可以在构建时指定包括哪些语言。可以用-H:IncludeLocales=en,nl
添加特定的语言,也可以用-H:+IncludeAllLocales
添加所有语言。默认的语言是用-H:DefaultLocale=ja
指定的。
多层编译改善了预热时间,现在默认启用了JavaScript、Python和Java on Truffle等Truffle语言使用的Polyglot Runtime。第一层优化了编译速度,并对琐碎的方法使用内联方法。第二层使用GraalVM的所有优化。新的实验性编译队列功能进一步改善了预热时间,可以用--engine.TraversingCompilationQueue
启用。
在GraalVM 21.0中加入Java on Truffle后,进行了一些改进。调试现在更快,因为启用仪器化不再导致问题。当应用程序结束时,应用程序中的关闭钩子现在会按预期执行。
Java应用程序可以利用Java on Truffle提供的客人Java Polyglot API。例如,Context.safepoint()
方法可用于在主机方法运行时轮询线程-本地行动。Context
类可用于检查中断或取消的情况。HotSpot的一个实验性功能提供了指定最大堆内存的能力,以限制内存使用客人Truffle语言。这是用:--sandbox.MaxHeapMemory=<size>
调用的。Java Polyglot API现在支持与字节缓冲区、迭代器、可迭代和地图相当的数据结构。在各种客体语言实现这些功能后,它们的工作方式与它们的本地功能一样。
在企业版中有几个针对循环的增强功能。编译器现在可以检测并矢量处理具有哈希码模式的循环,其中哈希码的计算类似于c\*哈希+array[i]
。颠倒的循环,如do-while循环,现在和其他循环一样被优化,有防护优化、矢量化、完全解卷和部分解卷。测试表明,性能改进高达40%。在while循环的每一次迭代中都会进行检查,如果索引高于数组长度,就会抛出一个ArrayIndexOutOfBoundsException
。GraalVM通过提取验证并将其置于循环之前来优化该部分。然而,这意味着总是要进行验证,即使没有进入循环。GraalVM通过使用倒置的循环解决了这个问题。
关于这些新功能的更多细节,可以在GraalVM的首席开发者倡导者Oleg Šelajev和Thomas Wuerthinger,GraalVM创始人和项目负责人介绍的开箱的GraalVM 21.1版本!中找到。