小師妹學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的部落格
歡迎關注我的公眾號:程式那些事,更多精彩等著您!