首页
学习
活动
专区
工具
TVP
发布
社区首页 >问答首页 >Java -二进制代码与ByteCode相同吗?

Java -二进制代码与ByteCode相同吗?
EN

Stack Overflow用户
提问于 2011-01-30 12:05:24
回答 6查看 26.3K关注 0票数 33

在Java中,“二进制代码”的意思是否与"Java字节码“相同?

这就是Java中的流程吗?

Java File (.java) -> javac -> ByteCode File (.class) -> Java虚拟机/Java解释器->运行它(首先将其转换为特定于机器的二进制代码)

谢谢!

EN

回答 6

Stack Overflow用户

回答已采纳

发布于 2011-01-30 12:09:02

答案取决于你说的binary code.是什么意思

Java bytecode是一种二进制数据格式,包括用于Java虚拟机的加载信息和执行指令。从这个意义上说,Java bytecode是一种特殊的二进制代码

当您使用术语“二进制代码”来表示用于实际处理器体系结构(如IA-32或Sparc)的机器指令时,它就不同了。

从这个意义上讲,Java bytecode不是二进制代码。它不是特定于处理器的。

票数 39
EN

Stack Overflow用户

发布于 2011-02-06 02:22:19

JVM是一个非常复杂的程序,其流程在一定程度上是不可预测的。例如,HotSpot JVM内部的流程如下所示:

1)它获取您的字节码并解释它

2)如果某个方法执行得相当频繁(在某个时间跨度内的某些次数),则将其标记为“热”方法,并且JVM将其编译调度到依赖于平台的机器码(这就是您所说的二进制代码吗?)。该流程如下所示:

代码语言:javascript
复制
ByteCode
--> Hige-level Intermediate Representation (HIR)
  --> Middle-level Intermediate Representation (MIR)
    --> Low-level Intermediate Representation (LIR)
      --> Register Allocation
        --> EMIT (platform dependent machine code)

该流程中的每一步都很重要,可以帮助JVM对代码进行一些优化。当然,它不会改变你的算法,优化只是意味着可以检测到一些代码序列,并与性能更好的代码进行交换(产生相同的结果)。从LIR阶段开始,代码变得依赖于平台(!)。

字节码可以很好地用于解释,但还不够好,无法轻松转换为机器本机代码。HIR负责处理它,其目的是将字节码快速转换为中间表示。MIR将所有操作转换为三个操作数的操作;ByteCode基于堆栈操作:

代码语言:javascript
复制
iload_0
iload_1
iand

这是简单and操作的字节码,中间层表示如下:

代码语言:javascript
复制
and v0 v1 -> v2

LIR依赖于平台,考虑到我们使用and操作的简单示例,并将我们的平台指定为x86,那么我们的代码片段将是:

代码语言:javascript
复制
x86_and v1 v0 -> v1
x86_move v1 -> v2

因为and操作需要两个操作数,第一个是目标,另一个是源,然后我们将结果值赋给另一个“变量”。下一个阶段是“寄存器分配”,因为x86平台(可能还有大多数其他平台)使用寄存器,而不是变量(如中间表示),也不是堆栈(如字节码)。在这里,我们的代码片段应该如下所示:

代码语言:javascript
复制
x86_and eax ecx -> eax

在这里你可以注意到没有“移动”操作。我们的代码只包含一行,并且JVM认为不需要创建一个新的虚拟变量;我们只需重用eax寄存器。如果代码足够大,有许多变量,并且密集地使用它们(例如,在下面的某个地方使用eax,所以我们不能更改它的值),那么您将看到机器代码中的左移操作。这又是关于优化的问题:)

这是JIT流程,但根据VM的实现,可能还有一个步骤-如果代码被编译(被“热”),并且仍然被多次执行,JVM会调度该代码的优化(例如,使用内联)。

那么,结论是,从字节码到机器码的路径非常有趣,有点不可预测,并且依赖于许多很多东西。

顺便说一下,上面描述的过程被称为“混合模式解释”(当JVM首先解释字节码,然后使用JIT编译),这种JVM的例子是HotSpot。一些JVM(比如Oracle中的JRockit )只使用即时编译。

这是对那里正在发生的事情的非常简单的描述。我希望它有助于在非常高的层次上理解JVM内部的流程,并针对字节码和二进制代码之间的差异这一问题。对于参考,以及这里没有提到的和该主题相关的其他问题,请阅读类似的主题"Why are compiled Java class files smaller than C compiled files?“。

也请随意批评这个答案,指出我的错误或误解,我总是愿意提高我的JVM知识:)

票数 14
EN

Stack Overflow用户

发布于 2011-01-30 12:15:11

没有“机器独立字节码”这样的东西(如果你想一想,这是没有任何意义的)。字节码(在本答案中)仅用于虚拟机之类的东西。JVM(比如JVM) 解释字节码,并使用一些巧妙而复杂的实时编译(依赖于机器/平台)来为您提供最终产品。

因此,在某种意义上,这两个答案都是对的,也是错的。Java编译器将代码编译成Java字节码(独立于机器)。字节码所在的*.class文件是二进制的,毕竟它们是可执行的。虚拟机随后解释这些二进制*.class文件(注意:当将文件描述为二进制文件时,它有点用词不当),并执行各种令人惊叹的事情。JVM通常使用JIT (just-in-time compilation,即时编译),它可以生成特定于平台或特定于机器的指令,从而加快执行的各个部分。然而,JIT是另一个话题。

编辑

代码语言:javascript
复制
Java File (.java) -> [javac.exe] -> ByteCode File (.class) -> [JVM/Java Interpreter] -> Running it(by first converting it into binary code specific to the machine)

这是不正确的。JVM不会“转换”任何东西。它只是简单地解释字节码。JVM中唯一“转换”字节码的部分是在调用JIT编译器时,这是一种特殊情况,不应泛化。

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

https://stackoverflow.com/questions/4841083

复制
相关文章

相似问题

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