Just-In-Time(JIT)编译器是Java运行环境的一个组件,它可以在运行时改善Java应用程序的性能。
Java程序是由类构成的,包含平台无关的字节码,可以在许多不同的计算机体系构架上被JVM解释。在运行时,JVM加载类文件,确定每一个独立的字节码的语意,并且执行适当的计算。解释中会消耗额外的计算和内存,意味着Java的程序会比一个本地的(原生的)应用程序执行得更慢。JIT编译器帮助改善Java程序的性能,是通过在运行时将字节码编译成本地的(原生的)机器码。
JIT编译器默认是启用的,当一个Java方法被调用时被激活。JIT编译器将方法的字节码编译成本地机器码,“及时”编译它到运行。当一个方法已经被编译,JVM用直接调用被编译的方法的代码的方式,代替解释。理论上,如果编译不需要处理器时间与内存占用,编译每一个方法可以让Java程序速度接近于本地(原生)的应用程序。
JIT编译不需要处理器时间和内存占用。当JVM首次启动时,成千上万的方法被调用。尽管编译所有的方法会显著的影响启动时间,却可以让程序最终达到最好的性能。
实践中,方法不是在它们第一次被调用时编译的。对于第一个方法,JVM维护一个调用计数,方法每次被调用都增长一次。JVM解释一个方法一直到它调用的计数超过了JIT编译的阈值。所以,经常使用的方法是在JVM启动后不久就被编译了,使用较少的方法编译得比较慢,或者根本就不会被编译。JIT编译的阈值有助于JVM的快速启动的同时,还能提高性能。这个阈值必须谨慎选择,以便在启动时间和长期性能之间找到最佳平衡。
一个方法被编译以后,它的调用计数被重置为0,随后调用这个方法继续增长它的计数。当一个方法的调用计算达到了JIT重新编译的阈值,JIT编译器将第二次编译这个方法,应用更大的优化选择比上一次编译。这个过程一直重复到最大的优化级别。Java程序中最繁忙的方法一直被优化到最优,达到使用JIT编译器的最大的收益。JIT编译器还能够在运行时测量操作数据,以便用这些数据提升下次重编译的质量。
JIT编译能够被关闭。在这种情形下,全部的Java程序都将使用解释模式。不推荐关闭JIT编译器,除非为了诊断或者解决围绕JIT编译器而出现的问题。