2011-08-02 49 views
26

有什麼辦法可以對Java即時編譯器生成的本機代碼進行彙編轉儲嗎?反彙編Java JIT編譯好的本地字節碼

和相關的問題:有沒有辦法使用JIT編譯器不運行的JVM編譯我的代碼到本機代碼?

+0

異端!不,開玩笑吧。有趣的問題! +1 –

+0

你如何獲得這個「即時」編譯代碼?因爲它是在運行時在飛行中完成的,所以我想知道如何訪問它以在其上執行程序集轉儲... –

+3

您的第一個問題很奇怪,但第二個問題表明您應該對該主題進行一些閱讀。按定義JIT編譯依賴於僅在運行時可用的信息,因此就像您在問是否有任何方法使用MP3編碼器來編碼歌曲而無需先錄製歌曲。 – entonio

回答

16

是,there is a way打印所生成的本機代碼(需要的OpenJDK 7)。

沒有,有沒有辦法來編譯Java字節碼使用JDK的JIT本機代碼,並保存爲本地可執行。

即使這是可能的,它可能沒有你想象的那麼有用。 JVM執行一些非常複雜的優化,並且如果需要的話,它甚至可以動態地優化代碼。換句話說,並不像JIT將代碼編譯爲本地機器語言那樣簡單,然後在程序運行時本機機器語言將保持不變。此外,這不會讓您創建獨立於JVM和運行時庫的本機可執行文件。

2

您不能使用JIT產生一個獨立的可執行文件,你需要一些其他的系統,如GCJ。至於看到JIT生成的代碼,請查看OpenJDK源代碼以查找調試選項。您可以創建自己的副本並啓用JIT,或者添加自己的增強功能以​​輸出任何您喜歡的內容。

3

如果Amigable克拉克康德認爲你的問題是異端,他真的會翻出了這個答案。在「Justin建議」下不一定要填寫「可能的內容」。 :-)

一個選項是使用IKVM.NET來使用Mono來處理您的Java代碼。 IKVM.NET允許您在.NET or the Mono CLR之上運行Java代碼。有人可能會說,你正在以這種方式跳過JVM,儘管說IKVM.NET真的是在CLR上運行的JVM的實現更準確。

無論如何,如果你這樣做,你現在在做Ahead-of-time (AOT)編譯使用Mono你的代碼的選項。也就是說,您可以將代碼一直編譯到機器本地,這意味着您在運行時不需要CLR或JVM。

與Jesper上面說的不同,使用AOT編譯實際上可以獲得更好的性能。儘管JVM(和CLR)在運行時執行一些在編譯時不可能的優化是確實的,但反過來也是如此。此外,其中一個選項是使用LLVM進行代碼生成,這通常會導致更好的性能。

下面是簡而言之管道:

你的代碼 - > IKVM.NET - >單 - > LLVM - >本地可執行

或者,只是使用被設計爲AOT生成Java編譯器本地可執行文件(如GCJExcelsior Jet)。

Mono/IKVM.NET選項可能有用的一個地方是如果您想將Java庫用作iPhone應用程序的一部分(使用MonoTouch)。 App Store只允許本機二進制文件。

編輯:您還可以使用LLVM VMKit AOT編譯Java代碼機器碼。這與我在Mono中描述的過程在概念上是相同的,但是保留了那些令人討厭的CIL東西。

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