导读:在Java中,JIT 编译通过在运行时将字节码转换为本机代码来提升 Java 性能,优化执行并平衡启动速度。
在计算领域,执行用高级语言编写的程序需要将源代码编译成低级语言或原生语言。这种编译被称为“提前编译”(AOT),通常在代码构建时完成,这能够有效地减少运行时的工作量。
对于 Java 来说,AOT 会生成一个中间二进制文件,即字节码,然后在Java 虚拟机 (JVM)执行期间将其转换为本机机器码。这符合 Java 的 “一次编写,随处运行”(WORA)理念, 或者简单地说,达到平台独立性。
在程序执行过程中,JVM 会识别出 那些可以优化的频繁运行的代码(称为 热点) 。这种优化由即时 (JIT) 编译器在运行时完成。非常有趣的是:HotSpot VM 的名字也由此而来。
JIT 广泛应用于 .NET、JavaScript V8 等编程语言,以及 Python 和 PHP 的某些环境中。本文将仅讨论 Java 中的即时 (JIT)。
有趣的是,代码可以被多次(重新)编译,以进行更高级别的优化,这取决于 JIT 的判断。
虽然 JIT 会不断努力提升或优化性能,但在某些情况下,优化后的方法可能不再适用。此外,编译器对优化的假设也可能因方法的行为而异。对于这种情况,JIT 会暂时将优化级别恢复到之前的级别,或直接恢复到 0 级。
请注意,这些方法可以使用更新的配置文件信息再次进行优化。但是,建议监控此类切换,并相应地调整源代码,以降低频繁切换的成本。
JIT 和分层编译默认启用。但仍可能出于某些重要原因(例如诊断 JIT 引发的错误,这种情况实际上非常罕见)而禁用它们,因此应避免禁用。
要禁用 JIT,请在 JVM 启动期间指定-Djava.compiler=NONE
或作为参数。-Xint
要禁用分层编译,可以指定-XX:-TieredCompilation
。
对于粒度控制,即仅使用 C1 编译器,请指定-XX:TieredStopAtLevel=1
。
要控制从 2 到 4 的各个层级的相应阈值,请参阅如下格式(使用时将 Y 替换为层级的数字):
-XX:TierYCompileThreshold=0
-XX:TierYInvocationThreshold=100
-XX:TierYMinInvocationThreshold=50
-XX:TierYBackEdgeThreshold=1500
请注意,调整任何配置都会影响程序的性能。因此,建议在进行全面的基准测试后再进行调整。
GraalVM JIT 是另一种技术实现,其与 JDK HotSpot JIT 的核心区别如下:
本质上说,HotSpot 仍然是一个久经考验且稳定的 Java 应用程序运行平台,而 GraalVM 凭借其现代 JIT 编译器和附加运行时功能突破了性能和灵活性的界限。
两者之间的选择通常取决于具体的工作负载以及应用程序的性能或互操作性要求。
JIT 编译通过在运行时将字节码转换为原生代码来提升 Java 程序的性能,优化常用方法并平衡启动速度。分层编译通过基于性能分析数据逐步优化代码,进一步完善了这一过程。虽然默认的 JIT 设置效果良好,但微调配置需要仔细进行基准测试,以防止出现性能问题。
对于大多数应用程序来说,这些优化可以无缝运行,无需开发人员干预。然而,了解即时 (JIT) 编译对于高性能应用程序至关重要,因为微调编译设置会显著影响执行效率。
作者:洛逸
参考:
https://en.wikipedia.org/wiki/Just-in-time_compilation
https://docs.oracle.com/en/java/javase/21/vm/java-hotspot-virtual-machine-performance-enhancements.html
https://developers.redhat.com/articles/2023/09/29/how-we-solved-hotspot-performance-puzzle#problem_and_solution
本文为 @ 场长 创作并授权 21CTO 发布,未经许可,请勿转载。
内容授权事宜请您联系 webmaster@21cto.com或关注 21CTO 公众号。
该文观点仅代表作者本人,21CTO 平台仅提供信息存储空间服务。