关于传统解释器,编译器和JIT编译器/解释器(JAVA)的说明

我正在学习Java,以下事情对我来说有点混乱.我理解的是:

Java Compiler-> Java编译器只是将.java程序转换为.class文件,
 这意味着将我们的源代码转换为字节代码(它是虚拟机(JVM)的操作码代码列表,它使java,平台无关).
Java Interpreter->仅仅“解释”代码并且不会将其转换为本机机器代码.它将每个指令逐个字节代码作为命令执行,并执行它,无论同一条指令发生多少次.(这就是为什么它很慢而java引入了JIT概念.)

JIT编译器 – >这也在执行时出现.JIT能够通过缓存已经被转换的代码块的结果来提高性能 – 与每次发生时简单地重新评估字节码中的每一行或操作数相比.

现在我有几个问题.

1.由于我的物理处理器只了解原生机器代码如何使用JVM的Interpreter执行java程序,因为解释器不会将字节代码转换为本机代码.除非有人将机器代码放入内存,否则物理处理器将无法执行它.

2.不知何故,解释器还将ByteCode转换为本机机器代码然后“使用缓存执行代码块(JIT)和逐行执行(Interpreter)”是唯一区分JIT和解释器的东西?

3.如果在执行时,JIT将字节码转换为本机机器代码(用于执行程序)为什么java没有提前使用编译,就像生成JVM相关的字节码(这反过来使得Java Plateform独立),带来它在目标机器上(我们想要执行它)并将其转换为本机机器代码(在C编译的情况下制作.exe或.out等).这可能是因为我们每个人都有一个特定的JVM system.This比使用JIT快得多,因为它需要一些时间来编译/加载程序,并且它仍然是平*立的,只需分发Bytecode(在从Bytecode到M / c Code的最终转换之前生成).

如果这是一个愚蠢的问题,请原谅我.

解决方法:

免责声明:用一粒盐将所有这些都拿走;它太简单了.

1:你是对的,计算机本身不理解代码,这就是JVM本身需要的原因.让我们假装XY意味着“在堆栈中添加前两个元素并推送结果”.然后JVM将实现如下:

for(byte bytecode : codeToExecute) {
    if (bytecode == XX) {
        // ...do stuff...
    } else if (bytecode == XY) {
        int a = pop();
        int b = pop();
        push(a+b);
    } else if (bytecode == XZ) {
        // ...do stuff...
    } // ... and so on for each possible instruction ...
}

JVM在计算机的本机机器代码中实现了每个单独的指令,并基本上查找每个字节码块以了解如何执行它.通过JITting代码,您可以通过省略这种解释来实现大的加速(即查找应该如何处理每个指令).那,和优化.

2:JIT并没有真正运行代码;一切仍然在JVM中运行.基本上,JIT在适当的时候将一大块字节码转换为机器码.当JVM遇到它时,它会认为“哦,嘿,这已经是机器代码!很好,现在我不必仔细检查每个字节,因为CPU自己理解它!我只是把它抽出来,一切都会神奇地自行完成!“

3:是的,理论上可以以这种方式预编译代码,以避免解释和JITting的早期开销.但是,通过这样做,你会失去一些非常有价值的东西.您会看到,当JVM解释代码时,它还会保留有关所有内容的统计信息.当它然后JIT代码时,它知道不同部分的使用频率,允许它在重要的地方进行优化,以牺牲稀有东西为代价,使常见的东西更快,从而产生整体性能提升.

上一篇:linux – 使用静态Swift核心库编译Swift脚本


下一篇:如何编译支持旧版Java的.java?