java机器码在相同的硬件上会相同吗?

Mic*_*ang 0 java jvm bytecode

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

但是我想知道如果我有一台 x86 机器,无论我选择安装哪个操作系统,由平台相关的 JVM 翻译的机器代码是否相同?

Ste*_*n C 10

TL; DR - 不,不会。

JIT 编译器从相同的字节码、相同的 Java 版本和相同的操作系统生成的本机代码仍然可能不同

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

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

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

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

  • 自分析(例如确定热点)取决于在某些情况下可能很微妙的时间。因此,我不仅会说,生成的代码可能会随着系统负载而变化,甚至可能会出现虚假的差异,而没有明显的原因。一些编译任务与应用程序线程(以及同一台机器上的其他进程)同时运行,因此它们的进度可能会受到它们的影响,这反过来又会影响以后的编译决策(例如,一个任务的减慢可能会为该任务提供更多元信息)下一个)。 (2认同)
  • 通常有多个 JIT 编译器线程(至少一个 C1 和一个 C2),并且它们在后台工作。由于时间不是确定性的,编译顺序可能不同,生成的代码也可能不同(因为它取决于许多因素,包括运行时配置文件、编译历史记录、编译队列的长度等)我已经见过很多次了,特别是在微基准测试上,即使系统负载没有显着变化,生成的代码每次运行都会有所不同。 (2认同)