小師妹學JVM之:JIT中的PrintAssembly

簡介

想不想了解JVM最最底層的運行機制?想不想從本質上理解java代碼的執行過程?想不想對你的代碼進行進一步的優化和性能提升?

如果你的回答是yes。那麼這篇文章非常適合你,因爲本文將會站在離機器碼最近的地方來觀看JVM的運行原理:Assembly。

使用PrintAssembly

小師妹:F師兄,上次你給我介紹了java中的字節碼,還有JIT中的LogCompilation和PrintCompilation的用法。雖然都非常有用,但是能不能更進一步,讓我能以機器的眼光來看待JVM的執行?

小師妹,如果要探究JVM的運行本質,那就應該是機器碼了。難道你要去讀懂機器碼?雖然我不是機器碼的專家,但我猜那應該是個非常複雜的過程。

小師妹:F師兄,當然不是機器碼,有沒有比機器碼更高級一點點的,我記得上大學的時候學過彙編語言,好像就是離機器碼最近的語言了,JVM有沒有相應的彙編語言呢?

必須有的,我們可以使用-XX:+PrintAssembly來將assembly打印出來。

但是打印assembly是有條件的,它就像一個高傲的姑娘,不是你想追求就能追求得上的。

我們使用下面的命令來查看系統對PrintAssembly的支持程度:

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version

Java HotSpot(TM) 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
Could not load hsdis-amd64.dylib; library not loadable; PrintAssembly is disabled
java version "1.8.0_171"
Java(TM) SE Runtime Environment (build 1.8.0_171-b11)
Java HotSpot(TM) 64-Bit Server VM (build 25.171-b11, mixed mode)

根據大家的運行環境的不同,得到的結果可能也是不同的,我是mac的系統,從上面的結果可以看到,在我的JDK8的環境中,顯示缺少hsdis-amd64.dylib,所以PrintAssembly其實是禁用的。

小師妹:F師兄,那現在咋辦呀?沒有hsdis-amd64.dylib就用不了PrintAssembly了。

巴甫洛夫說過:問號是開啓任何一門科學的鑰匙。沒有問題我們就創造問題,沒有困難我們就製造困難,沒有hsdis-amd64.dylib當然是安裝咯。

具體怎麼安裝,大家自行探索吧,網上有很多安裝的教程,這裏就不一一介紹了。

這裏想討論一個很奇怪的事情,雖然在JDK8環境中,我們不能使用PrintAssembly,因爲沒有hsdis-amd64.dylib。但是當我切到最新的JDK14環境中,一切都很美好,PrintAssembly可以正常運行了。

如果我們在JDK14中同樣運行上面的命令,我們會得到下面的結果:

上圖說明JDK14中雖然可以正常運行但是結果卻不是assembly code,說明在JDK14中還是需要安裝hsdis-amd64.dylib才能夠得到正確的assembly結果。

注意,JDK14也需要安裝hsdis-amd64.dylib才能正確使用。

輸出過濾

默認情況下,PrintAssembly輸出的是所有的信息,但是JDK內部的代碼我們不可能進行修改,一般來說並不關心他們的assembly輸出,如果要指定我們自己編寫的方法,可以使用CompileCommand:

CompileCommand=print,*MyClass.myMethod prints assembly for just one method
CompileCommand=option,*MyClass.myMethod,PrintOptoAssembly (debug build only) produces the old print command output
CompileCommand=option,*MyClass.myMethod,PrintNMethods produces method dumps

例如:

-XX:CompileCommand=print,com.flydean.PrintAssemblyUsage::testPrintAssembly

這樣我們可以得到,只屬於testPrintAssembly方法的輸出:

總結

本文講解了怎麼使用PrintAssembly來輸出JVM的彙編日誌。我們會在後面繼續講解這些Assembly code到底有什麼用。

本文的例子https://github.com/ddean2009/learn-java-base-9-to-20

本文作者:flydean程序那些事

本文鏈接:http://www.flydean.com/jvm-jit-printassembly/

本文來源:flydean的博客

歡迎關注我的公衆號:程序那些事,更多精彩等着您!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章