如果JIT执行字节码转换成机器指令,那么JVM有什么用处?

37

我真的很难理解以下事情

之前我知道:

当Java程序被编译时,会生成.class文件。在这个文件中代码以字节形式存在。然后JVM将把这些字节码转换成机器可读的格式。

现在我在SO的一个问题中看到了以下内容

即时编译器(JIT)是运行时解释器的一项功能,它不会在每次调用方法时都解释字节码,而是将字节码编译成正在运行的机器代码指令

所以在这里,JIT将字节码转换为机器指令。那么JVM的作用是什么?我们能够通过JIT做到这一点。在我的认识中,JIT只是用来改善JVM的性能。

4个回答

41
JIT只是JVM的一部分。其他部分包括字节码解释器、类加载验证和链接机制以及用于反射、I/O等内容的本地代码支持。
从这个意义上讲,JIT并没有使JVM运行更快。相反,它使Java代码比JVM仅仅解释它时运行得更快。
实际上,JVM确实开始解释字节码。在一段时间后,JVM使用其JIT编译器将经常使用的方法编译为本机代码,并利用在解释期间收集到的统计信息来调整问题所涉及的代码。
顺便说一下,你引用的这段文本有些笨拙且技术上不准确:
"Just-In-Time (JIT) compiler是运行时解释器的一个功能... (context)"
实际上,JIT不是解释器的一个功能。相反,JIT是JVM的功能,与解释器一起工作。

2
清楚一点:
JVM执行所有操作,例如:
它位于操作系统的顶部,并在编译的Java程序和操作系统之间提供抽象。这样,Java编译程序不必担心它必须工作的平台。 Java程序将代码编译为JVM可以理解和执行的字节码。
JIT
当JVM编译类文件时,它不会完整地完成整个类文件; 它仅按需编译其中的一部分。这避免了完整源代码的重型解析。这种编译称为JIT或即时编译。 JVM是平台(OS)相关的代码生成 JIT是面向平台的,生成本机字节码,因此比JVM更快 :)

但是我看到 JIT 语句一次编译整个类文件。但在你的语句中,JVM 正在进行编译。请解释一下。 - Anusha
@Anusha 是的...JVM会逐行进行编译,它是Java的本地解释器..但JIT是可选的,它也进行编译,但不是所有的方法/函数都编译。 举个例子: JIT编译器不检查Java边界条件,如空指针或数组越界异常。 JIT编译器知道它有一个空指针异常的唯一方法是通过操作系统发出的信号。 - Abraham K
这是错误的。javac Java编译器解析Java源代码并将其编译为Java字节码(机器无关),生成.class文件。JIT编译器将该字节码编译为本地机器代码(CPU架构特定)。JIT输出的机器代码仍然执行边界检查和Java异常处理。 - arjunyg

2
Java虚拟机(JVM)提供了运行Java程序的整个环境。它与操作系统集成,加载类并运行程序。即时编译器(JIT)只是一个小组件,可以通过禁用(-Xint)来关闭,但启用后可以提高性能。曾经有过不包含JIT的JVM实现,也有像传统语言(如C或C ++)一样将Java预编译为机器代码的实现。

-1

它会在即时编译器中进行优化,以便与JVM兼容。


这并没有回答问题。 - Stephen C

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接