选择性地禁用 JIT 或 AOT 编译器

如果 Java™ 程序故障指向 JIT 或 AOT 编译器的问题,那么可以尝试进一步缩小问题的范围。

关于本任务

缺省情况下,JIT 编译器以不同的优化级别对方法进行优化。 根据方法的调用计数,对不同的方法应用不同的优化选择。 经常调用的方法会在较高级别上进行优化。 通过更改 JIT 编译器参数,您可以控制用于优化方法的优化级别。 您可以确定优化器是否出错,如果出错,还可以确定哪个优化存在问题。

缺省情况下,AOT 编译器会在 warm 优化级别编译方法。 强制 AOT 编译器在更高级别编译方法虽然可行,但不受支持。

您可以采用逗号分隔的列表形式来指定 JIT 参数,该列表将附加到 -Xjit 选项。 语法为 -Xjit:<param1>,<param2>=<value>。 例如:
java -Xjit:verbose,optLevel=noOpt HelloWorld
可以运行 HelloWorld 程序,启用 JIT 详细输出,并在不执行任何优化的情况下使 JIT 生成本机代码。 优化选项在 -Xjit中列出。 使用 -Xaot 选项,以相似的方式来控制 AOT 编译器。 诊断 JIT 编译器问题时,使用 -Xjit 选项;诊断 AOT 编译器问题时,使用 -Xaot 选项。

按照以下步骤来确定编译器的哪个部分导致故障:

程序

  1. 设置 JIT 或 AOT 参数 count=0 以将编译阈值更改为零。 此参数导致在运行每个 Java 方法之前对其进行编译。
    仅当您诊断问题时才使用 count=0,因为这会编译更多方法,包括不经常使用的方法。 额外的编译会使用较多的计算资源,从而导致应用程序速度变慢。
    利用 count=0,当到达问题区域时,您的应用程序会立即失败。 在某些情况下,使用 count=1 可以更可靠地重现故障。
  2. disableInlining 添加到 JIT 或 AOT 编译器参数。
    disableInlining 会禁止生成更大、更复杂的代码。
    如果不再发生该问题,请在 Java 服务团队分析并修复编译器问题时使用 disableInlining 作为变通方法。
  3. 通过添加 optLevel 参数来降低优化级别,然后再次运行程序,直到故障不再发生,或者达到 noOpt 级别为止。 对于 JIT 编译器问题,请从 scorching 入手并依次使用下一个列表项。 对于 AOT 编译器问题,请从 warm 开始,然后向下处理列表。
    这些优化级别按降序排列为:
    1. scorching
    2. veryHot
    3. hot
    4. warm
    5. cold
    6. noOpt

下一步

如果其中一个设置使故障消失,表明您找到了可以使用的变通方法。 在 Java 服务团队分析和解决编译器问题时,此变通方法是暂时的。 如果从 JIT 或 AOT 参数列表中移除 disableInlining 并不会导致故障重新出现,这样做可以提高性能。 遵循 查找失败方法 中的指示信息以提高变通方法的性能。

如果仍在 noOpt 优化级别发生故障,那么作为变通方法,您必须禁用 JIT 或 AOT 编译器。