阅读了一些关于新GraalVM的高级文章,认为使用它来提高JUnit测试性能是个好主意,特别是对于以分叉模式运行的大型测试套件而言。
根据那么,“GraalVM JVM支持java 11吗?”,我在eclipse中为单元测试运行配置的VM参数添加了以下内容(jee-2019-12,JUnit4):
-XX:+UnlockExperimentalVMOptions -XX:+UseJVMCICompiler效果:单元测试比没有这些开关的时间要长一些(有2800毫秒,没有2200毫秒,可复制)。
我错过了什么吗?还是我误解了在GraalVM中增加引导时间的承诺?
发布于 2020-01-24 14:48:22
是的,不幸的是,这里好像有一些误会。我将在这里详细阐述一些关于性能和GraalVM的问题。
GraalVM是一个polyglot运行时,它可以运行JVM应用程序,通常是通过运行HotSpot VM (例如,与OpenJDK JDK相同),并将顶级优化实时编译器替换为自己的GraalVM编译器。简化一些,在运行过程中,JVM加载类文件,验证它们,开始解释它们,然后用一系列编译器编译它们,这些编译器倾向于从最快的编译到最优化的--所以应用程序运行的时间越长,使用的方法越多--它们被逐步编译成一个更好、更好的机器代码。
GraalVM编译器非常擅长优化代码,所以当应用程序运行足够的时间并开始工作时,结果通常比其他编译器所能显示的要好。这将带来更好的峰值性能,这对您的中期/长期工作负载非常有用。
您的单元测试运行需要2秒,实际上执行代码、收集概要文件和使用优化编译器的时间并不多。也可能是特定的代码模式和工作负载非常适合于C2 (默认热点的顶级JIT),因此很难做得更好。请记住,C2是一个优秀的JIT,它已经开发了至少20年,而且它的结果也非常非常好。
现在,GraalVM还提供了另一个选项-- GraalVM本地图像,它允许您提前编译代码(AOT)到不依赖于JVM的本地二进制文件,并且不会加载类、验证它们、初始化它们,所以在执行有用的“业务”工作之前启动这样的二进制程序要好得多。对于运行较短的工作负载或资源受限环境,这是一个非常有趣的选项(二进制文件不需要进行JIT编译,因此它不需要资源,从而使运行时资源消耗更小)。然而,要使用这种方法,您需要使用来自GraalVM的本机映像实用程序编译应用程序,它可能比在2秒内运行的工作负载花费的时间更长。
现在,在您所描述的设置中,您不是使用GraalVM发行版,而是在您的OpenJDK发行版中启用GraalVM编译器(我假设)。指定将GraalVM编译器打开为顶级JIT编译器的选项。与从java发行版运行GraalVM相比,有两个主要的区别:
在GraalVM发行版中,我认为这个实验是最新的,GraalVM编译器是最新的,默认情况下,它是使用GraalVM本地映像技术作为共享库预编译的,所以在运行时不需要编译JIT,所以它的预热更类似于C2的特性。
不过,对于优化编译器来说,2秒可能不足以显示主要的差异。也可能是测试一次运行大量代码,而JIT编译的热代码的主体不够重要。
https://stackoverflow.com/questions/59874763
复制相似问题