【发布时间】:2017-05-20 17:56:29
【问题描述】:
我试图了解 Java 源代码是如何执行的,但我对 JVM 中的 JIT 编译器实际上是什么感到困惑。首先,让我告诉你我如何理解从 Java 源代码到在计算机上执行机器代码的过程。也许,我在导致混乱的过程中误解了一些东西。
步骤:
- 源代码编译成字节码(.class文件)
- 类文件被加载到 JVM(在 RAM 中)
- 字节码经过验证,然后由 JIT 编译器处理
- JIT 编译器的输出是准备好执行的机器代码
现在,根据Wikipedia article on JVM,更具体地说,“字节码解释器和即时编译器”部分,为了执行 Java 字节码,您需要一个 解释器(但我们有JIT 编译器)。
现在让我感到困惑的是。我把它分解成引号:
“当解释器执行 Java 字节码时,执行速度总是比编译成本机机器语言的相同程序的执行速度慢。”
-
既然计算机只能执行机器码,而解释器将字节码翻译成机器码的速度比编译器慢,为什么 JVM 使用解释器而不是编译器?
-
为什么我们没有另一个由 JIT 编译器为 CPU 生成的中间可执行文件,以便它可以快速执行指令?
“JIT 编译器可以在执行程序时将 Java 字节码翻译成本地机器语言。程序的翻译部分可以比它们被解释的速度更快地执行。这种技术被应用于这些部分一个经常执行的程序。”
JIT 编译器真的是一个能够编译频繁执行的代码的解释器吗?编译器和解释器这两个术语是否被错误地互换使用?
提前致谢。
【问题讨论】:
-
“JIT Compller”这个词已经过时了。它指的是 1.3 之前的 JVM 插件架构,它在执行之前编译所有字节码。发现“JIT 编译器到处喷洒代码”,这导致了我们现在所拥有的,称为“HotSpot”,它选择性地根据其执行历史编译字节码。根据您的 Wikipedia 引文,目前的趋势是使用“JIT”来指代两者,但实际上这只是令人困惑,而且在历史上也不准确。
-
@EJP 感谢您的回复。当您说它指的是两者时,您是指编译器和解释器吗?所以如果我理解正确的话,起初JVM内部的翻译器是一个编译器,但由于安全问题被替换了。这意味着在 1.3 之前,从源代码到机器代码的整个翻译过程有 2 个单独的编译步骤。一个从源代码到字节码,另一个从字节码到机器码。目前,翻译器更像是逐行执行代码的解释器,偶尔充当常用代码的编译器。对吗?
-
我想知道的另一件事是机器代码究竟是如何到达 CPU 的。我假设当代码逐行处理时,解释器只是传递该机器代码。不那么明显的是,当您有一个包含机器代码的中间文件时,CPU 如何获取机器代码。编译器是否从文件中提供 CPU 指令?
-
我的意思是,您引用的 Wikipedia 文章将 JIT 编译器和 HotSpot JVM 称为同一个东西,它们不是一个国家英里。我试图编辑它一次,但思想警察反对。 1990 年代后期的情况是 JIT DLL 由第三方(例如 Symantec)提供,并通过 JVM 的命令行选项启用,这顺便回答了您上面的另一个问题,而 HotSpot内置在 JVM 中,并通过命令行选项禁用。在 JIT 或 HotSpot 下没有包含机器代码的中间文件。