Graal 编译器

Graal 编译器是用 Java 编写的动态编译器,它将字节码转换为机器码。Graal 即时(JIT)编译器与 Java HotSpot 虚拟机和 GraalVM 集成。有关更多信息,请参见 Java 虚拟机指南 和部分 GraalVM 作为虚拟机。(Graal JIT 编译器的开源代码可在 GitHub 上获得。)

编译器优势 #

Graal JIT 编译器通过代码分析和优化的独特方法,为在 Java 虚拟机 (JVM) 上运行的应用程序提供优化的性能。它包括多种优化算法(称为“阶段”),例如积极内联、多态内联等。

Graal 编译器可以为高度抽象的程序带来性能优势。例如,它包含部分逃逸分析优化,可以消除某些对象的昂贵分配。有关更多信息,请参见 GraalVM GitHub 存储库中 CEOptimization 枚举 中的值 PartialEscapeAnalysis。优化确定新对象何时在编译单元外部可访问,并且仅在“逃逸”编译单元的路径上分配它(例如,如果对象作为参数传递、存储在字段中或从方法返回)。这种方法可以通过减少堆分配次数来极大地提高应用程序的性能。使用更现代的 Java 功能(如流或 Lambda 表达式)的代码将看到性能的更大提升,因为此类代码涉及大量此类非逃逸或部分逃逸对象。受 I/O 或内存分配等特性限制的代码,这些特性无法通过编译器删除,将看到较少的改进。有关性能调优的更多信息,请参阅 Graal JIT 编译器配置

图形编译 #

为了在与主机 JVM 基语言相同的运行时中运行客机编程语言(即 JavaScript、Python 和 Ruby),编译器与源语言和要生成的机器码之间的语言无关中间图形表示一起工作。(有关语言互操作性的更多信息,请参见 互操作性。)

图形可以以相同的方式表示不同语言的类似语句,例如“if”语句或循环,这使得在同一个应用程序中混合语言成为可能。Graal 编译器随后可以在此图形上执行语言无关优化并生成机器码。

诊断数据 #

如果编译器抛出未捕获的异常,则通常会丢弃编译并继续执行。Graal 编译器可以生成诊断数据(例如立即表示图形),这些数据可以与错误报告一起提交。这通过 -Djdk.graal.CompilationFailureAction=Diagnose 选项启用。诊断输出的默认位置是当前进程工作目录下的 graal_dumps/ 目录,但可以使用 -Djdk.graal.DumpPath 选项更改。在 JVM 关闭期间,包含诊断数据的存档的位置将打印到控制台。

此外,可以使用 -Djdk.graal.Dump 选项为 Graal 编译器执行的任何编译生成诊断数据。这将为编译器编译的每个方法生成诊断数据。

要细化生成诊断数据的哪些方法集,请使用 -Djdk.graal.MethodFilter=<class>.<method> 选项。例如,-Djdk.graal.MethodFilter=java.lang.String.*,HashMap.get 将仅为 java.lang.String 类中的方法以及名称为 get 的方法生成诊断数据,这些方法的非限定名称为 HashMap

联系我们