java字节代码(编译语言和其他称为目标代码)与机器代码(当前计算机的本机代码)之间的区别是什么。我在书中读到他们将字节代码称为二进制指令,我不知道为什么。
答案 0 :(得分:7)
Bytecode是独立于平台的,由运行在windows中的编译器编译的字节码仍将在linux / unix / mac中运行。机器代码是特定于平台的,如果它是在Windows x86中编译的,它将仅在Windows x86中运行。
继续阅读你的书籍=)
答案 1 :(得分:3)
字节码是Java虚拟机的机器语言。当JVM加载类文件时,它会为类中的每个方法获取一个字节码流。字节码流存储在JVM的方法区域中。在运行程序的过程中调用该方法时,将执行方法的字节码。它们可以通过解释,即时编译或特定JVM的设计者选择的任何其他技术来执行。
方法的字节码流是Java虚拟机的一系列指令。每条指令由一个单字节操作码组成,后跟零个或多个操作数。操作码表示要采取的行动。如果在JVM采取操作之前需要更多信息,则该信息将被编码为紧跟操作码的一个或多个操作数。
每种操作码都有助记符。在典型的汇编语言风格中,Java字节码流可以用它们的助记符表示,后跟任何操作数值。例如,以下字节码流可以被分解为助记符:
// Bytecode stream: 03 3b 84 00 01 1a 05 68 3b a7 ff f9
// Disassembly:
iconst_0 // 03
istore_0 // 3b
iinc 0, 1 // 84 00 01
iload_0 // 1a
iconst_2 // 05
imul // 68
istore_0 // 3b
goto -7 // a7 ff f9
字节码指令集设计得紧凑。除了两个处理表跳转的指令外,所有指令都在字节边界上对齐。操作码的总数足够小,因此操作码只占用一个字节。这有助于最小化在由JVM加载之前可能通过网络传播的类文件的大小。它还有助于保持JVM实现的大小。
JVM中的所有计算都集中在堆栈上。由于JVM没有用于存储abitrary值的寄存器,因此必须先将所有寄存器压入堆栈,然后才能将其用于计算。因此,字节码指令主要在堆栈上运行。例如,在上面的字节码序列中,局部变量乘以2,首先使用iload_0指令将局部变量推入堆栈,然后使用iconst_2将两个推入堆栈。在将两个整数都推入堆栈之后,imul指令有效地将两个整数从堆栈中弹出,将它们相乘,然后将结果推回堆栈。结果从堆栈顶部弹出,并通过istore_0指令存储回本地变量。 JVM被设计为基于堆栈的机器,而不是基于寄存器的机器,以便在缺少寄存器的架构(如Intel 486)上实现高效实现。