Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/380.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
java机器代码在同一硬件上是否相同?_Java_Jvm_Bytecode - Fatal编程技术网

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

java机器代码在同一硬件上是否相同?,java,jvm,bytecode,Java,Jvm,Bytecode,我知道java源代码将被编译成字节码,JVM将解释该字节码并将其转换为底层平台的本机代码 但是我想知道,如果我有一台x86机器,无论我选择安装哪个操作系统,由依赖平台的JVM翻译的机器代码是否相同?对于相同的操作系统,它可能相同或非常相似。然而,不同的操作系统以完全不同的方式实现大多数事情。例如,对于大多数函数,在Linux中使用中断,在Windows中使用WINAPI调用。此程序集代码写入Linux上的文件: mov eax, 4 ; system call for write mov ebx

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


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

对于相同的操作系统,它可能相同或非常相似。然而,不同的操作系统以完全不同的方式实现大多数事情。例如,对于大多数函数,在Linux中使用中断,在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库使用它们自己的抽象,但归根结底,像这样的调用是用来与系统通信的。任何东西生成的本机代码通常不仅依赖于硬件,还依赖于操作系统。例外情况是某种程序不以任何方式与操作系统接口(添加两个数字,但从不打印任何内容),这是一种无用的程序。

TL;DR-不会的

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

  • 生成的代码可能取决于JVM运行的物理硬件;e、 g.核心数量、芯片组等

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

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


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

谢谢您的回复!生成的代码是否取决于CPU、内存等的使用率?例如,系统繁忙时生成的机器代码将不同于系统空闲时生成的机器代码。(使用相同的硬件、操作系统、java版本)自我评测,例如确定热点,取决于在某些场景中可能很微妙的时间安排。因此,我不仅要说,生成的代码可能会随着系统负载的变化而变化,甚至可能会出现虚假的差异,没有明显的原因。某些编译任务与应用程序线程(以及同一台计算机上的其他进程)并行运行,因此它们的进度可能会受到影响,进而影响以后的编译决策(例如,一个任务的速度减慢可能会使更多元信息可用于下一个任务)。通常有多个JIT编译器线程(至少一个C1和一个C2),它们在后台工作。由于计时不是确定的,编译顺序可能不同,生成的代码也可能不同(因为它取决于许多因素,包括运行时配置文件、编译历史、编译队列长度等)。我已经多次看到,尤其是在微基准上,生成的代码在不同的运行中有所不同,即使系统负载没有明显变化,我认为这与所问的问题无关。JIT编译器不会生成执行您正在讨论的调用类型的代码。您向我们展示的汇编代码将是特定于操作系统的可执行文件或本机代码库的一部分。cde将提前创建,而不是在运行时创建。