首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >JVM是将字节码编译成机器代码并运行它,还是直接运行字节码?

JVM是将字节码编译成机器代码并运行它,还是直接运行字节码?
EN

Software Engineering用户
提问于 2021-09-08 10:56:10
回答 4查看 1.3K关注 0票数 1

Java源代码被编译成JVM的字节码。但是,JVM如何将字节码转换为机器代码呢?它是否将字节码重新编译成机器代码,然后运行它?或者它只是直接运行字节码?

EN

回答 4

Software Engineering用户

回答已采纳

发布于 2021-09-08 11:08:26

字节码通常不能直接在处理器上运行,因为硬件没有aloadgetfield等操作码。

JVM要么解释字节码,即在某些内部数据结构中查找每个操作码在硬件上要做的事情,要么将字节代码编译成真正的机器代码,并在调用Java例程时简单地调用编译过的代码。这是一个有趣的问题,也是许多优化研究的课题。

票数 2
EN

Software Engineering用户

发布于 2021-09-08 12:11:02

Java源代码被编译成JVM的字节码。

这不一定是真的。在Java语言规范中没有规定任何特定的实现策略。JLS只指定运行代码的结果,但不指定如何实现这些结果。

根据JLS,为Java编写解释器是完全合法的。或者将其编译成本机代码。或者将其编译成CLI CIL。或者将其编译成ECMAScript

编译Java到JVM字节码是一种可能的实现,但肯定不是唯一可能的实现。这甚至不是唯一已经做过的事。有一些编译器直接将Java编译成本机代码,例如(GCJ)。有一些编译器将Java编译成ECMAScript (例如,GWTJ2CL)。我看到了一些将Java编译成Perl、C、PHP、Scheme、Parrot、C#、CIL和许多其他的玩具示例。

虽然不一定所有这些都实现了完整的Java语言规范,但没有什么能从根本上阻止它们这样做。

但是,JVM如何将字节码转换为机器代码呢?

没有,至少没必要。它也可以解释它,而不是将它转换成机器代码。或者它可以把它转换成另一种语言。

Java虚拟机规范中没有规定任何特定的实现策略。JVMS只指定运行代码的结果,而不指定如何实现这些结果。

实际上,这在这些规范中很常见。通常,设计人员尽量避免指定任何特定的实现,并给实现者尽可能多的回旋余地。规范对实现的约束越多,优化的空间就越小。

因此,JVMS没有指定JVM必须解释字节码。它也没有指定JVM必须编译字节码。它只指定字节码的含义,而不是如何执行字节码。

这有时被称为AS-IF规则:只要运行代码的结果看起来像是按照规范的规则执行了代码,实现者就可以做他们想做的任何事情。一个例子是消除没有副作用的循环.因为您实际上无法判断循环是否被执行,所以取消循环是合法的,因为代码的结果就像循环已经执行一样。

它是否将字节码重新编译成机器代码,然后运行它?

JVMS中没有任何东西可以禁止这一点,但在JVMS中也没有任何东西可以强制这样做。

每个实现者都可以自由选择如何实现JVMS。

或者它只是直接运行字节码?

JVMS中没有任何东西可以禁止这一点,但在JVMS中也没有任何东西可以强制这样做。

每个实现者都可以自由选择如何实现JVMS。

我只举几个已有的或历史悠久的JVM实现的例子:

  • 最初的Sun是一个纯解释器。它从来不编译任何东西,它总是被解释。
  • 精益喷射机是一个纯粹超前的编译器.它提前静态地将JVM字节码编译成本机代码。(还有一个具有JIT编译器的运行时库,用于无法提前编译的代码,例如,因为它是在运行时生成或在运行时加载的。)没有解释器,也没有代码被解释。
  • GCJ也是一个纯粹超前的编译器.它可以编译Java到原生、Java到JVM和JVM到原生.
  • picoJava中央处理器可以直接执行JVM字节码。
  • Maxine研究VM是一个元循环JVM,它本身完全是用Java编写的。
    • Maxine使用了两个带有没有翻译的纯实时编译器:T1X是一个快速、非优化的编译器,第二个编译器C1X是一个更积极的优化JIT编译器,实际上是对C1编译器的HotSpot重写。
    • 稍后的迭代添加了Graal编译器,它实际上是作为Maxine的一部分开发的,后来移植到HotSpot中。
    • 在此过程中的某个时候,他们还试验了跟踪JIT。
    • 我相信有计划在某个时候增加一个翻译,但我不确定一个是否已经开发。

  • 月食OpenJ9 9 / IBM J9解释字节码一段时间,并保存一个计数器,其中的代码被执行多久一次。一旦确定了这些所谓的“热点”,就会将它们编译成本机代码。
  • Oracle HotSpot JVM解释字节码一段时间,并保留一个计数器,其中的代码被执行多久一次。一旦确定了这些所谓的“热点”,就会使用三种编译器之一将它们编译成本机代码。

我在这里写了一些关于实现一种语言的不同方法的东西,以防您感兴趣:理解差异:传统解释器、JIT编译器、JIT解释器和AOT编译器。

票数 7
EN

Software Engineering用户

发布于 2021-09-08 11:06:43

JVM如何将字节码转换成机器代码?

您需要的关键字是"JIT编译“;JIT代表”刚好及时“,即它在尝试执行字节码之前立即运行。

请参阅这是来自甲骨文的解释。

它是否将字节码重新编译成机器代码,然后运行它?

通常是的。

直接运行字节码?

它不能“直接”运行,除非处理器本身支持Java字节码(ARM Jazelle,从未真正成功),所以如果它没有被编译,那么它就会被解释,即一个单独查看每个字节码并执行适当操作的程序。

票数 2
EN
页面原文内容由Software Engineering提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://softwareengineering.stackexchange.com/questions/431737

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档