当我的应用程序启动时,我经常调用一个对性能至关重要的方法。最终,它会被 JIT 编译,但不是在解释器中运行一段时间之后。
有什么方法可以告诉 JVM 我希望从一开始就编译此方法(无需使用类似的东西调整其他内部结构-XX:CompileThreshold
)?
当我的应用程序启动时,我经常调用一个对性能至关重要的方法。最终,它会被 JIT 编译,但不是在解释器中运行一段时间之后。
有什么方法可以告诉 JVM 我希望从一开始就编译此方法(无需使用类似的东西调整其他内部结构-XX:CompileThreshold
)?
我知道的唯一方法是-Xcomp
标志,但通常不建议使用。它会在所有类和方法第一次运行时强制它们立即进行 JIT 编译。缺点是您会在初始启动时看到性能下降(由于 JIT 活动增加)。此标志的另一个主要限制是它似乎禁用了 JIT 通常会执行的基于增量分析的优化。在标准混合模式下,JIT 编译器可以(并且将)根据收集的分析和运行时信息不断地去优化和重新编译部分代码。这允许它“纠正”错误的优化,例如被省略但被证明是需要的边界检查、次优内联等。-Xcomp
禁用基于分析的优化并取决于程序,可能会导致整体性能显着下降,而启动时只有很小的实际收益或没有实际收益,这就是不建议使用它的原因。
除了-Xcomp
(非常残酷)和-XX:CompileThreshold
(控制 JIT 将在解释模式下运行多少次给定方法以在编译/优化之前收集统计信息)之外,还有-Xbatch
. 这迫使 JIT 编译到“前台”,实质上是在编译之前阻止对方法的调用,而不是像通常那样在后台编译它。
您没有指定您使用的是哪个 Java 版本,但如果您可以选择 Java 7,它会引入一个新的 JIT 模型,称为“分层编译”(通过-XX:+TieredCompilation
开关激活)。分层编译的作用是,它允许在第一次使用方法时进行初始的、较小的编译传递,而不是稍后基于收集的分析数据进行额外的、更大的编译/优化。听起来你应该很有趣。
据说它需要一些额外的调整和参数/配置,但我没有时间进一步检查它。
我不确定它是否会完全预编译代码,但您可以将具有关键方法的类添加到 JVM 的共享数据转储中。有关更多详细信息,请参阅此问题。
另外,你考虑过JNI吗?如果您的方法是 CPU 密集型的,它可能会大大加快速度。