反汇编Java JIT编译的本机字节码

问题描述 投票:0回答:5

有什么方法可以对 Java 即时编译器生成的本机代码进行程序集转储吗?

还有一个相关的问题:有没有办法在不运行 JVM 的情况下使用 JIT 编译器将我的代码编译为本机机器代码?

java jvm jit disassembly
5个回答
17
投票

是的,有一种方法可以打印生成的本机代码(需要 OpenJDK 7)。

不,无法使用 JDK 的 JIT 将 Java 字节码编译为本机代码并将其保存为本机可执行文件。

即使这是可能的,它也可能没有你想象的那么有用。 JVM 会进行一些非常复杂的优化,如果有必要,它甚至可以动态取消优化代码。换句话说,它并不像 JIT 将代码编译为本机机器语言那么简单,然后在程序运行时该本机机器语言将保持不变。此外,这不会让您创建独立于 JVM 和运行时库的本机可执行文件。


4
投票

如果友善的克拉克·康德认为你的问题是异端邪说,他真的会对这个答案感到愤怒。将其归档在“可能的情况”下,不一定在“贾斯汀建议”下。 :-)

一种选择是使用 IKVM.NET 使用 Mono 处理 Java 代码。 IKVM.NET 允许您在 .NET 或 Mono CLR 上运行 Java 代码。有些人可能会说您以这种方式跳过了 JVM,尽管更准确的说法是 IKVM.NET 实际上是在 CLR 上运行的 JVM 的实现。

无论如何,如果您这样做,您现在可以选择使用 Mono 进行代码提前 (AOT) 编译。也就是说,您可以将代码一直编译为机器本机,这意味着您在运行时不需要 CLR 或 JVM。

与 Jesper 上面所说的不同,使用 AOT 编译实际上可以带来更好的性能。虽然 JVM(和 CLR)确实在运行时执行了一些在编译时不可能执行的优化,但反之亦然。此外,其中一种选择是使用 LLVM 进行代码生成,这通常会带来更好的性能。

简而言之,这是管道:

您的代码 -> IKVM.NET -> Mono -> LLVM -> 本机可执行文件

或者,只需使用旨在 AOT 从一开始就生成本机可执行文件的 Java 编译器(如 GCJExcelsior Jet)。

Mono/IKVM.NET 选项可能有用的一个地方是,如果您想使用 Java 库作为 iPhone 应用程序的一部分(使用 MonoTouch)。 App Store 仅允许本机二进制文件。

编辑: 您还可以使用 LLVM VMKit 将 Java 代码 AOT 编译为机器代码。从概念上讲,这与我用 Mono 描述的过程相同,但将那些令人讨厌的 CIL 内容排除在外。


3
投票

您无法使用 JIT 生成独立的可执行文件,您需要一些其他系统,例如 GCJ。 至于查看 JIT 生成的代码,请查看 OpenJDK 源代码以查找调试选项。 您可以使用启用的副本构建您自己的副本,并查看 JIT 正在做什么,或者添加您自己的增强功能以输出您喜欢的任何内容。


1
投票

查看 Oracle Solaris Studio 性能分析器。我在一次会议上看到查理亨特演示了它,它简直令人惊叹。 它允许您对 Java 应用程序进行运行时调试和反汇编,即查看实际突出显示热点的机器指令。 另请参阅本书摘录:http://charliehunt.ulitzer.com/node/2067673

更多文档:Oracle Solaris Studio 12.2:性能分析器


1
投票

是的,我也认为很难获得 JIT 本机输出,但是这篇论文不断显示本机代码,但没有说明他如何获得输出。我可以理解 JIT 编译器的输出是否不一致,因为它会不时发生变化,或者从代码缓存中清除,稍后重新生成,但是如何获得某些代码块的某些程序集的快速快照。 :|

http://www.google.com/url?sa=t&rct=j&q=Java+annotation+for+optimization&source=web&cd=15&ved=0CKEBEBYwDg&url=http%3A%2F%2Floome.cs.uiuc.edu%2Fpubs% 2Fjones-kamin.pdf&ei=8vj-UN63C-bQ2QX-9IDoDQ&usg=AFQjCNEegMNXLwKyUTTJ5ljgnP7X9rPXHg&bvm=bv.41248874,d.b2I

© www.soinside.com 2019 - 2024. All rights reserved.