常见的 Java 源代码,首先通过 javac 编译成字节码(bytecode),然后字节码通过 JVM 解释为机器码执行。此时 JVM 可以理解为解释执行模式。这也是常见的说法:Java 是解释执行的语言。

但是在常见的 JVM 中,例如 Oracle JDK 的 Hotspot JVM ,里面提供了 JIT(Just-In-Time)编译器,也就是通常所说的动态编译器,JIT 能够在运行时将热点代码编译成机器码,这种情况下部分热点代码就属于编译执行,而不是解释执行。

解释执行

使用 -Xint 参数,可以指定 JVM 只通过解释执行,不对代码进行编译。这种模式会降低运行速度,因为它抛弃了 JIT 的性能优势。

java -Xint -version
java version "1.8.0_71"
Java(TM) SE Runtime Environment (build 1.8.0_71-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, interpreted mode)

编译执行

使用 -Xcomp 参数,可以指定 JVM 关闭解释器,从而不进行解释执行。这种模式会在第一次运行时候,将字节码编译成机器码。此模式会导致启动速度变慢,同时有些 JIT 的优化方式:分支预测…… 得不到对应优化。

java -Xcomp -version
java version "1.8.0_71"
Java(TM) SE Runtime Environment (build 1.8.0_71-b15)
Java HotSpot(TM) 64-Bit Server VM (build 25.71-b15, compiled mode)

混合模式

JVM 默认的执行模式,参数是 -Xmixed ,此模式部分函数会解释执行,部分会编译执行。如果函数调用频率高,被反复使用,就会认为是热点代码,该函数就会被编译执行。

文章目录