【发布时间】:2017-07-30 10:49:04
【问题描述】:
我对 JIT 编译器感到困惑,
- 什么是 JIT 编译器?
- JIT 编译器在每次执行之前或每次 JVM 加载时编译字节码?
【问题讨论】:
标签: java compiler-construction jit
我对 JIT 编译器感到困惑,
【问题讨论】:
标签: java compiler-construction jit
JIT 代表“及时”。它是一个编译器,可在您的程序运行时将 Java 字节码转换为本机机器码。
Sun 的 JIT 不会在您每次运行 Java 程序时预先编译所有字节码。它包含一些非常复杂的逻辑来决定何时编译部分字节码,它使用的标准之一是代码的执行频率。
有关详细信息,请参阅 Just-in-time compilation 和 HotSpot(维基百科)。
【讨论】:
JIT 编译器是一个专门的编译器,它会监视 Java bye 代码的运行,并在必要时将其编译为本机指令。
如果 JIT 确定您的代码的一部分运行非常频繁,或者将其编译为本机代码会显着提高性能,它会这样做。
JIT 编译是完全可选的,Java 的标准实现允许您将其关闭。但是,确实没有理由将其关闭。
【讨论】:
-Xint 关闭 JIT 编译,但通常您不会这样做。
即时 (JIT) 编译器是将 Java 字节码(包含必须解释的指令的程序)转换为可直接发送到处理器的指令的程序。
JIT 编译器作为独立的平台相关本机库提供。如果 JIT Compiler 库存在,Java VM 会初始化 Java Native Interface (JNI) 本机代码挂钩,以调用该库中可用的 JIT 函数,而不是解释器中的等效函数。java.lang.Compiler 类用于加载本机库并在 JIT 编译器中启动初始化。JIT 编译器使用自己的调用程序。 Sun 生产版本检查方法访问位的值 ACC_MACHINE_COMPILED 以通知解释器此方法的代码已经编译并存储在加载的类中。当第一次调用方法时(取决于 JVM 供应商),JIT 编译器编译方法块转换为该方法的本机代码,并将其存储在该方法的代码块中。
编译代码后,在 Sun 平台上使用的 ACC_MACHINE_COMPILED 位被设置。
首先要记住的是,JIT 编译器在第二次调用方法时(取决于 JVM 供应商)实现了大部分速度改进。 JIT 编译器确实编译了整个方法,而不是逐行解释它,这在运行启用了 JIT 的应用程序时也可以提高性能。这意味着如果只调用一次代码,您将不会看到显着的性能提升。 JIT 编译器也会忽略类构造函数,因此尽可能将构造函数代码保持在最低限度。
JIT 编译器还通过不预先检查某些 Java 边界条件(例如 Null 指针或数组越界异常)来实现较小的性能提升。 JIT 编译器知道它有空指针异常的唯一方法是通过操作系统引发的信号。因为信号来自操作系统而不是 Java VM,所以您的程序会受到性能影响。为确保在使用 JIT 运行应用程序时获得最佳性能,请确保您的代码非常干净,没有出现 Null 指针或数组越界异常等错误。
参考:http://java.sun.com/developer/onlineTraining/Programming/JDCBook/perf2.html
【讨论】:
JIT 编译器是 Java 1.1 附带的外部即时编译器。该术语现已过时。 Java 附带一个内置编译的“HotSpot”JVM。
【讨论】: