问题描述
我目前正在优化一个特定的方法,不幸的是它被 JVM 内联,这会阻止它被正确地向量化。我注意到有一个禁止内联的注释,即 jdk.internal.vm.annotation.DontInline
。但是,它不能从默认模块访问。
是否有一种干净的方法可以访问此注释或以其他方式防止有问题的方法内联?
解决方法
DontInline
、ForceInline
等是JDK内部注解,不能应用于用户代码。即使您设法打开这些注释,HotSpot JVM 也有一个 explicit check 来禁止非特权类使用它们。
原因是可以理解的。这些注释是特定 JVM 版本的实现细节; JDK 开发人员可以在不通知的情况下随意添加/删除/更改此类注释的含义,即使是在 JDK 小更新中也是如此。
无论如何,使用 @DontInline
强制矢量化似乎不是一个好方法。一般来说,内联不应该阻止其他优化。如果您遇到此类问题,最好在 hotspot-compiler-dev 邮件列表中报告问题。
现在是好消息。
从 JDK 9 开始,有一个公共支持的 API 来手动调整 JIT 编译器。这是JEP 165: Compiler Control。
这个想法是在单独的 JSON 文件中提供编译器指令,并使用 -XX:CompilerDirectivesFile=<file>
选项启动 JVM。如果您的应用程序对某些编译器决策敏感,您可以随应用程序一起提供指令文件。
{
match: "*::*",inline: "-org/package/MyClass::hotMethod"
}
甚至可以使用 DiagnosticCommand API 在运行时以编程方式应用编译器指令:
ManagementFactory.getPlatformMBeanServer().invoke(
new ObjectName("com.sun.management:type=DiagnosticCommand"),"compilerDirectivesAdd",new Object[]{new String[]{"compiler.json"}},new String[]{"[Ljava.lang.String;"}
);
顺便说一下,指令列表中有 Vectorize: true
选项,这可能有助于向量化特定方法。