有没有办法对Java即时编译器生成的本机代码进行汇编转储?
还有一个相关的问题:有没有办法在不运行JVM的情况下使用JIT编译器将我的代码编译成本地机器代码?
答案 0 :(得分:17)
是,there is a way打印生成的本机代码(需要OpenJDK 7)。
不,没有办法使用JDK的JIT将Java字节码编译为本机代码,并将其保存为本机可执行文件。
即使这是可能的,也可能没有您想象的那么有用。 JVM进行了一些非常复杂的优化,如果需要,它甚至可以动态地对代码进行去优化。换句话说,它并不像JIT将代码编译为本机机器语言那么简单,然后在程序运行时本机语言将保持不变。此外,这不会让您创建独立于JVM和运行时库的本机可执行文件。
答案 1 :(得分:3)
您不能使用JIT生成独立的可执行文件,您需要一些其他系统,如GCJ。至于看到JIT生成的代码,请查看OpenJDK源以查找调试选项。您可以使用已启用的副本构建自己的副本,并查看JIT正在执行的操作,或者根据您的喜好添加自己的增强功能。
答案 2 :(得分:3)
如果Amigable Clark Kant认为你的问题是异端邪说,他会真的翻开这个答案。在“可能的”下提交此文件,而不一定在“Justin推荐”下。 : - )
一种选择是使用IKVM.NET使用Mono处理Java代码。 IKVM.NET允许您在.NET or the Mono CLR之上运行Java代码。有些人可能会说你正在以这种方式跳过JVM,尽管说IKVM.NET实际上是在CLR上运行的JVM的实现会更准确。
无论如何,如果你这样做,你现在可以选择用Mono编译Ahead-of-time (AOT)代码。也就是说,您可以将代码一直编译为机器本机,这意味着您在运行时不需要CLR或JVM。
与Jesper上面所说的不同,使用AOT编译实际上可以带来更好的性能。虽然JVM(和CLR)确实在运行时执行了一些在编译时无法实现的优化,但反过来也是如此。此外,其中一个选项是使用LLVM进行代码生成,这通常会带来更好的性能。
简而言之,这是管道:
您的代码 - > IKVM.NET - >单声道 - > LLVM - >本机可执行文件
或者,只需使用专为AOT设计的Java编译器从头开始生成本机可执行文件(如GCJ或Excelsior Jet)。
Mono / IKVM.NET选项可能有用的一个地方是,如果您想将Java库用作iPhone应用程序的一部分(使用MonoTouch)。 App Store仅允许本机二进制文件。
编辑:您还可以使用LLVM VMKit AOT编译Java代码来编写机器代码。这在概念上与我用Mono描述的过程相同,但是将那些令人讨厌的CIL东西排除在外。
答案 3 :(得分:1)
查看Oracle Solaris Studio Performance Analyzer。我看到Charlie Hunt在一次会议上演示它,这简直令人叹为观止。它允许您对Java应用程序进行运行时调试和反汇编,即查看实际突出显示的热点的机器指令。另见本书摘录:http://charliehunt.ulitzer.com/node/2067673
答案 4 :(得分:1)
是的,我也认为很难获得JIT原生输出,但这些家伙的纸张不断显示原生代码,但没有说明他是如何获得输出的。我可以理解JIT编译器的输出是否会不一致,因为它会不时更改,或者从代码缓存中清除只是为了稍后重新生成但是如何获得某些代码块的某些程序集的快照。 :|