编译和执行java程序?

时间:2017-09-16 07:10:55

标签: java jvm jit

我是java编程课程的初学者,到目前为止,这是我对编译和执行的整个java程序的理解。简要说明: -

  

1)java编译器将源代码(.java)文件转换为字节码(.class)(这是一个中间代码)。

     

2)这个字节码(.class)文件是平台无关的所以wooosh ....我可以复制它并把它带到另一台有JVM的平台机器上。

     

3)当我运行字节码时,作为JRE一部分的JVM首先验证       字节码,调用 JIT ,在运行时进行优化      它     有权访问动态     运行时信息。

     

4)最后JVM将中间代码解释为     处理器执行的一系列机器指令。 (处理器不能直接执行字节码,因为它不是本机代码)

我的理解是否正确?是否需要添加或更正?

2 个答案:

答案 0 :(得分:0)

首先,java只是一种编程语言。这意味着您可以(理论上)运行编译器来生成此字节码的本机二进制instad。 (见:Compiling a java program into an executable

我应该提到的另一件事是Java处理器能够直接执行java字节码...因为它的本机指令集(参见:https://en.wikipedia.org/wiki/Java_processor

答案 1 :(得分:0)

轮流拿走你的每一点:

1)这是正确的。 Java源代码由javac编译(尽管其他工具可以做同样的事情)并生成类文件。

2)再次,正确。类文件包含平台中立的字节码。这些是松散的“虚拟”机器(即JVM)的指令集。这就是Java实现自启动以来的“一次编写,随处运行”的想法。

3)部分正确。当JVM需要加载一个类时,它会对该类的字节码运行四阶段验证,以确保字节码的格式在JVM方面是合法的。这是为了防止生成可能破坏JVM的字节码序列(即类似病毒的行为)。但是,JVM此时不运行JIT。执行字节码时,它们以解释模式启动。每个字节码都会动态转换为所需的本机指令和OS系统调用。

4)与第3点结合使用时有点错误。

以下是简要说明的过程:

当JVM解释应用程序的字节码时,它还会分析频繁运行哪些字节码组。如果您有一个重复调用方法的循环,JVM会注意到这一点,并确定这是您代码中的热点(因此是Oracle JVM的名称)。一旦调用了足够多次的方法(可调),JVM将调用Just In Time(JIT)编译器为该方法生成本机指令。当再次调用该方法时,使用本机代码,从而消除了解释的需要,从而提高了应用程序的速度。此分析阶段导致Java应用程序的“预热”行为,其中代码的相关部分逐渐编译为本机指令。

对于基于OpenJDK的JVM,有两个JIT编译器,C1和C2(有时称为客户端和服务器)。 C1 JIT将更快地预热,但具有较低的最佳性能水平。 C2升温速度较慢,但​​对代码应用了更高级别的优化,从而提高了整体性能水平。

JVM也可以丢弃已编译的代码,因为它已经很长时间没有被使用(比如在缓存中),或者JIT所做的假设(称为推测优化)结果是错误的。这称为deopt,导致JVM返回解释模式,重新编译代码并可能使用JIT重新编译它。