如何在jvm

时间:2019-06-30 07:41:35

标签: java jvm

我已经读到一些文章说

  1. jvm将字节码转换为机器码
  2. jvm将字节码转换为本地代码
  3. jvm将字节码转换为系统调用,然后系统又与硬件进行通信

在上面哪个是正确的?翻译如何准确发生?什么是本机代码?是汇编语言代码吗?

1 个答案:

答案 0 :(得分:0)

我认为这个问题的结构不好,但是尝试回答仍然有一个价值。

我可以看到您的困惑,问题在于Java Interpreter的实际机制实际上与您在阅读解释器的高级描述时可能想到的完全不同。

首先,通过 javac 将Java(或其他基于JVM的语言)源代码编译为字节码。这样会生成一个相对简单的 .class 文件格式,该文件格式可能包含约200个字节码-这不是任何实际计算机都可以直接执行的格式;而是一种设计为由“虚拟机”(即JVM)执行的格式。

因此,为了能够在真实的机器上执行已编译的Java程序,我们需要将其“转换”为可执行的表示形式,即机器代码(与本机代码< / em>)。

默认情况下,JVM充当解释器:这意味着一次读取 .class 文件并执行一个字节码(操作码)。 解释器的作用是读取操作码并执行相应的操作-这会使操作变得更加复杂...

通常,您希望解释器有一个很大的 switch 语句,该语句涵盖所有可能的操作码,并根据遇到的字节码执行适当的操作,例如:

switch (opcode) {
  case iconst_1: handleIConst1();
  ...
}

此代码将是解释器(即JVM本身)的一部分,并且会提前编译为机器代码-安装特定于操作系统的JVM / JDK版本时会得到此代码。

但是,JVM解释器是一种称为 Template Interpreter 的特殊类型。 它不包含硬编码逻辑,但实际上维护了 opcodes 机器代码之间的映射的。 JVM启动时将填充此表(您可以通过-XX:+PrintInterpreter->需要hsdis库来查看此表)。 稍后,当JVM开始解释字节码时,解释器将在表中检查它是否具有机器代码所驻留的 code cache 的对应条目。如果是这样,则它直接执行机器代码;否则可能会退回到动态解析字节码的状态。

因此,我们拥有一个解释器,该解释器可以一对一地执行字节码。 此外,如果某些方法“足够热”(称为数千次),那么还会使用JIT。 JIT将启动并代替解释器-它将整个方法编译为本地代码,然后在目标计算机上执行。

最后,系统调用的问题与此无关。任何要访问硬件或其他敏感资源的程序都必须使用系统调用。它们不是您的程序的一部分,而是由操作系统提供的。

资源