我的理解是,通过调用javac
生成的Java字节码独立于底层操作系统,但HotSpot编译器将在程序运行时执行特定于平台的JIT优化和编译。
但是,我在Windows上使用32位JDK编译代码,并在Solaris下使用32位JVM执行它(OS都不是64位操作系统)。据我所知,Solaris x86机箱(确认其中的规格)应该在所有方面都优于Windows机箱(核心数,RAM数量,硬盘延迟,处理器速度等)。但是,相同的代码在Windows上运行速度要快得多(单个数据点在Windows上运行7.5秒,在Solaris上运行时间超过10秒)。我的下一个测试是在Solaris上编译并注意性能差异,但这对我来说没有意义,我找不到任何可以解释我所看到的Oracle文档。
鉴于JVM在两个不同操作系统上的相同版本(主要版本,次要版本,发行版本等),在相同源文件上调用javac
会导致Java字节码内的不同优化({{ 1}}文件产生)?有没有解释这种行为的文档?
答案 0 :(得分:4)
没有。 javac
不会在不同平台上进行任何优化。
请参阅oracle "tools"页面(其中描述了javac
和其他工具):
每个开发工具都有Microsoft Windows版本(Windows)和Solaris或Linux版本。 版本之间的功能几乎没有差异。但是,配置和使用方面存在细微差别,无法满足每个操作系统的特殊要求。 (例如,指定目录分隔符的方式取决于操作系统。)
(也许Solaris JVM比Windows JVM慢?)
答案 1 :(得分:1)
编译输出不应该依赖于调用javac的操作系统。 如果您想验证它,请尝试:
me@windows@ javac Main.java
me@windows@ javap Main.class > Main.win.txt
me@linux@ javac Main.java
me@linux@ javap Main.class > Main.lin.txt
diff Main.win.txt Main.lin.txt
答案 2 :(得分:1)
无论如何我决定谷歌。 ;)
http://java.sun.com/docs/white/platform/javaplatform.doc1.html
Java平台是一个新的软件平台,用于在联网的计算机系统上交付和运行高度交互,动态,安全的小程序和应用程序。但是,Java平台的独特之处在于它位于这些其他平台之上,并执行字节码,这些字节码并非特定于任何物理机器,而是虚拟机的机器指令。用Java语言编写的程序编译为一个字节码文件,该文件可以在任何底层操作系统上的Java平台存在的任何地方运行。换句话说,同一个确切的文件可以在运行Java平台的任何操作系统上运行。这种可移植性是可能的,因为Java平台的核心是Java虚拟机。
写于1996年4月30日。
一个常见的错误,特别是如果你是为C / C ++开发的,那就是假设编译器优化了代码。它只进行一次优化,即评估编译器时间已知常量。
编译器肯定不会像你想象的那样强大,因为它只是验证代码并生成尽可能匹配代码的字节代码。
这是因为字节码用于理想化的虚拟机,理论上不需要任何优化。希望当你以这种方式思考时,编译器确实做了很多工作,它不知道代码将如何实际使用。
相反,所有优化都由JVM中的JIT执行。这完全取决于平台,可以生成32位或64位代码,并使用运行代码的处理器的确切指令。它还将根据实际使用方式优化代码,静态编译器无法做到这一点。这意味着可以根据不同的使用模式对代码进行多次重新编译。 ;)
答案 3 :(得分:0)
扩展dacwe的部分“也许Solaris JVM比Windows JVM慢?”
有一些配置选项(例如,是否使用客户端或服务器vm [link],也可能是其他配置选项),其默认值因操作系统而异。这可能是Solaris VM在这里变慢的原因。
答案 4 :(得分:0)
据我所知,javac只考虑-target
参数来决定发出什么字节码,因此在字节码生成中没有特定的平台。
在解释字节代码时,所有优化都由JVM完成,而不是编译器。这是针对个人平台的。
此外,我在某处读过Solaris JVM是参考实现,然后将其移植到Windows。因此,Windows版本比Solaris版本更加优化。
答案 5 :(得分:0)
javac是否执行任何字节码级别优化,具体取决于 底层操作系统?
没有
确定在两个平台上程序的性能特征不同的原因需要在相同的工作负载下对其进行分析,并仔细分析方法执行时间和内存分配/ gc行为。你的程序是否进行任何I / O操作?