【问题标题】:Java's Virtual Machine's EndiannessJava 虚拟机的字节序
【发布时间】:2010-11-02 03:58:28
【问题描述】:

Java 在其虚拟机中使用什么字节序?我记得在某处读到它取决于它运行的物理机器,然后在我读过的其他地方我相信它总是大端。哪个是正确的?

【问题讨论】:

    标签: java virtual-machine endianness


    【解决方案1】:

    class 文件中的多字节数据以大端方式存储。

    来自The Java Virtual Machine Specification, Java SE 7 EditionChapter 4: The class File Format

    一个类文件由一个流组成 8 位字节。所有 16 位、32 位和 64 位量由以下方式构成 读二、四、八 连续的 8 位字节,分别。 始终存储多字节数据项 以大端顺序,其中高 字节在前。

    此外,如果字节码指令中的操作数跨越多个字节,它也是大端的。

    来自The Java Virtual Machine Specification, Java SE 7 EditionSection 2.11: Instruction Set Summary

    如果一个操作数超过一个字节 大小,然后存储在大端 order-high-order 字节在前。为了 例如,一个无符号的 16 位索引 局部变量存储为两个 无符号字节,byte1byte2,例如 它的值是(byte1 << 8) | byte2

    所以是的,我认为可以说Java虚拟机使用大端。

    【讨论】:

    • 这个答案极具误导性。所有参考资料都解释了多字节值如何存储在类文件中。并且类文件确实使用了大端。但是在运行时,我所知道的所有 Java 实现都以本机字节顺序存储变量和数据结构的数据。一旦类文件被加载为更好的可执行格式,它很可能也适用于指令操作数。在 i386 等小端架构上,其他一切都会非常缓慢。
    • JVM 可以从它执行的字节码的 POV 中呈现出大端序的外观,同时仍然实际上以原生字节序存储多字节值。这里有一个“as-if”规则在起作用,只要 JVM 从运行在其中的来宾代码的 POV 中表现出应有的行为,实际的实现细节就无关紧要了。例如将与 JIT 解释为本机代码。由于 Java 代码不能轻易地将 int 转换为 byte[],因此在 JVM 中运行的 Java 代码通常看不到这个细节,因此 JVM 很容易只使用原生 C int32_t
    • @Codo Java 在 i386 等小端架构上非常慢。如果指令集指定操作需要有大端参数,那么将它们存储为小端会导致更差的性能,因为您必须从小端转换为大端才能使用指令集,而指令集反过来将不得不反转到小端进行操作,结果将其转换为大端以匹配指令集规范,然后再返回到小端,仅将数据作为大端存储在结果文件中。
    【解决方案2】:

    存储在运行进程中的实际工作数据几乎肯定会匹配执行进程的字节序。通常文件格式(包括类文件)将按网络顺序(大端)。

    通常很难判断机器在下面做什么,因为它被虚拟机抽象掉了。您不能像在 C 和 C++ 中那样将 short[] 转换为 byte[]java.nio.ByteOrder.nativeOrder() 应该给你潜在的字节序。使用非字节 NIO 缓冲区时,匹配字节序很有用。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2011-05-08
      • 2023-03-06
      • 1970-01-01
      • 1970-01-01
      • 2015-08-21
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多