Java源代码被编译成JVM的字节码。但是,JVM如何将字节码转换为机器代码呢?它是否将字节码重新编译成机器代码,然后运行它?或者它只是直接运行字节码?
发布于 2021-09-08 11:08:26
字节码通常不能直接在处理器上运行,因为硬件没有aload、getfield等操作码。
JVM要么解释字节码,即在某些内部数据结构中查找每个操作码在硬件上要做的事情,要么将字节代码编译成真正的机器代码,并在调用Java例程时简单地调用编译过的代码。这是一个有趣的问题,也是许多优化研究的课题。
发布于 2021-09-08 12:11:02
Java源代码被编译成JVM的字节码。
这不一定是真的。在Java语言规范中没有规定任何特定的实现策略。JLS只指定运行代码的结果,但不指定如何实现这些结果。
根据JLS,为Java编写解释器是完全合法的。或者将其编译成本机代码。或者将其编译成CLI CIL。或者将其编译成ECMAScript。
编译Java到JVM字节码是一种可能的实现,但肯定不是唯一可能的实现。这甚至不是唯一已经做过的事。有一些编译器直接将Java编译成本机代码,例如(GCJ)。有一些编译器将Java编译成ECMAScript (例如,GWT、J2CL)。我看到了一些将Java编译成Perl、C、PHP、Scheme、Parrot、C#、CIL和许多其他的玩具示例。
虽然不一定所有这些都实现了完整的Java语言规范,但没有什么能从根本上阻止它们这样做。
但是,JVM如何将字节码转换为机器代码呢?
没有,至少没必要。它也可以解释它,而不是将它转换成机器代码。或者它可以把它转换成另一种语言。
在Java虚拟机规范中没有规定任何特定的实现策略。JVMS只指定运行代码的结果,而不指定如何实现这些结果。
实际上,这在这些规范中很常见。通常,设计人员尽量避免指定任何特定的实现,并给实现者尽可能多的回旋余地。规范对实现的约束越多,优化的空间就越小。
因此,JVMS没有指定JVM必须解释字节码。它也没有指定JVM必须编译字节码。它只指定字节码的含义,而不是如何执行字节码。
这有时被称为AS-IF规则:只要运行代码的结果看起来像是按照规范的规则执行了代码,实现者就可以做他们想做的任何事情。一个例子是消除没有副作用的循环.因为您实际上无法判断循环是否被执行,所以取消循环是合法的,因为代码的结果就像循环已经执行一样。
它是否将字节码重新编译成机器代码,然后运行它?
JVMS中没有任何东西可以禁止这一点,但在JVMS中也没有任何东西可以强制这样做。
每个实现者都可以自由选择如何实现JVMS。
或者它只是直接运行字节码?
JVMS中没有任何东西可以禁止这一点,但在JVMS中也没有任何东西可以强制这样做。
每个实现者都可以自由选择如何实现JVMS。
我只举几个已有的或历史悠久的JVM实现的例子:
我在这里写了一些关于实现一种语言的不同方法的东西,以防您感兴趣:理解差异:传统解释器、JIT编译器、JIT解释器和AOT编译器。。
发布于 2021-09-08 11:06:43
JVM如何将字节码转换成机器代码?
您需要的关键字是"JIT编译“;JIT代表”刚好及时“,即它在尝试执行字节码之前立即运行。
请参阅这是来自甲骨文的解释。
它是否将字节码重新编译成机器代码,然后运行它?
通常是的。
直接运行字节码?
它不能“直接”运行,除非处理器本身支持Java字节码(ARM Jazelle,从未真正成功),所以如果它没有被编译,那么它就会被解释,即一个单独查看每个字节码并执行适当操作的程序。
https://softwareengineering.stackexchange.com/questions/431737
复制相似问题