如何在jvm中将本机代码转换为机器代码 [英] How native code is converted into machine code in jvm

查看:295
本文介绍了如何在jvm中将本机代码转换为机器代码的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我已经读到一些文章说

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

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

In the above which one is true? How do translations happen exactly, and what is native code? Is it assembly language code?

推荐答案

我认为这个问题的结构很差,但是尝试回答它仍然有一个价值.

I think the question is poorly structured but there's still a value trying to answer it.

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

I can see your confusion and the problem is that the real mechanics of Java Interpreter are actually quite different from what you may imagine when you just read a high-level description of an interpreter.

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

To start with, Java (or another JVM-based language) source code is compiled into bytecode via javac. This produces a relatively simple .class file format which may contain ~200 bytecodes - this isn't a format that is directly executable by any real computer; rather it's a format designed to be executed by a "virtual machine", that is the JVM.

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

Therefore, to be able to execute compiled java programs on real machines we need to "convert" them into an executable representation, that is machine code (the same thing as native code).

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

By default, the JVM acts as an interpreter: that means the .class files are read and executed one bytecode (opcode) at a time. The role of the interpreter is to read the opcode and execute a corresponding action - this is where it gets more complicated...

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

Normally, you'd expect that the interpreter would have a big switch statement covering all possible opcodes and executing appropriate actions based on the bytecode it encounters like:

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

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

This code would be part of the interpreter (that is the JVM itself) and would be compiled to the machine code ahead of time - you get this when you install an OS-specific version of JVM/JDK.

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

However, the JVM interpreter is a special type called Template Interpreter. It doesn't contain a hardcoded logic but actually maintains a table of mappings between opcodes and machine code. This table is populated when the JVM is starting (you can see it via -XX:+PrintInterpreter -> requires the hsdis library). Later on, when JVM starts interpreting bytecodes the interpreter will check in the table whether it has a corresponding entry to the code cache where the machine code resides. If so, then it executes the machine code directly; otherwise it can fallback to resolving the bytecode dynamically.

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

So we have the interpreter which executes bytecodes one-by-one. Moreover, there's also JIT which is used if some method is "hot enough" (called thousands of times). The JIT will kick in and takes place of the interpreter - it will compile the whole method into native code which is then executed on the target machine.

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

Finally, the issue of system calls is unrelated to this matter. System calls have to be used by any program that wants to access hardware or other sensitive resources. They are not part of your program, rather they are provided by the OS.

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆