java 机器代码在相同的硬件上是否相同?

Will java machine code be the same on the same hardware?

我知道 java 源代码将被编译为字节码,JVM 将解释该字节码并将其转换为底层平台的本机机器码。

但我想知道如果我有一台x86机器,无论我选择安装哪个OS,依赖于平台的JVM翻译的机器代码是否相同?

与OS一样,很可能是相同或非常相似的。然而,不同的 OSes 以完全不同的方式实现大多数事情。例如,对于大多数函数,您在 Linux 中使用 interrupts,在 Windows 中使用 WINAPI 调用。此汇编代码写入文件 Linux:

mov eax, 4 ; system call for write
mov ebx, file_descriptor ; file descriptor
mov ecx, string ; data to write
mov edx, string_len ; data length
int 80h ; invoke interrupt

这对 Windows 也是如此:

push 0 
push 0
push string_len
push string
push hFile ; file handle
call _WriteFile@20

尽管 Java 库使用它们自己的抽象,但归根结底,像这样的调用是用来与系统通信的。任何东西生成的本机代码通常不仅依赖于硬件,而且还依赖于 OS。一个例外是某种不以任何方式与 OS 交互的程序(添加两个数字,但从不打印出任何东西),这有点没用。

TL;DR - 不会的。

JIT 编译器通过相同的 Java 版本和相同的 OS 从相同的字节码生成的本机代码仍然可能不同 .

  • 生成的代码可能 取决于 JVM 运行 所在的物理硬件;例如内核数、芯片组等。

  • 生成的代码甚至可以依赖于程序的输入。在 JIT 编译之前,JVM 使用字节码解释器来 运行 代码。此 自我分析 收集有关分支概率等的统计数据。这些统计信息由 JIT 优化器使用。由于在 运行 运行程序时采用的代码路径可能取决于程序输入,因此同一台机器上同一程序的不同 运行 最终可能会导致 JIT 编译器生成不同的本机代码。

  • 由于 JVM 预热期间的非确定性行为会影响自分析期间收集的统计数据,因此生成的代码甚至可能在 运行 上的相同代码之间有所不同具有相同输入的相同平台。

这就是 HotSpot JIT 编译的好处。它适应环境和应用程序的功能。但如果您的主要目标是获得 可重现 本机代码和 可重现 性能特征,这可能会成为一个问题。