(點選上方公眾號,可快速關註)
來源:劉正陽 ,
liuzhengyang.github.io/2017/07/27/jitwatch/
背景
我們知道Java程式碼透過編譯器編譯成位元組碼,一般是class檔案,有JVM的各個類載入器載入後,根據JVM的啟動配置可以進行解釋執行和編譯執行,編譯執行是由JIT(Just In Time)Compiler將位元組碼編譯成原生代碼來提高執行速度,缺點是編譯本身會消耗時間並且會佔用堆外空間(codecache中), 但是一般Server應用記憶體足夠且能夠忍受啟動時的略微緩慢。
檢視Java原始碼對應的bytecode可以透過javap來實現。
有時候我們想排查問題或者瞭解底層是如何實現的,就需要檢視JIT編譯後的彙編程式碼是什麼樣的,Hotspot提供了-XX:+PrintAssembly選項來輸出編譯後的彙編程式碼,缺點是輸出日誌量巨大,並且難以和程式碼中的對應起來。
JITWatch是一個檢視JIT行為的視覺化工具。
使用
安裝和啟動JitWatch
git clone https://github.com/AdoptOpenJDK/jitwatch
cd jitwatch
./gradlew run
給JDK新增Hsdis
參考我的Github上的說明hsdis
https://github.com/liuzhengyang/hsdis
透過以下命令檢測下是否安裝成功
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version
啟動一個應用,並且配置輸出日誌
在應用中新增如下JVM引數
-XX:+UnlockDiagnosticVMOptions
-XX:+TraceClassLoading
-XX:+LogCompilation
-XX:LogFile=/tmp/mylogfile.log
-XX:+PrintAssembly
-XX:+TraceClassLoading
然後在/tmp/mylogfile.log中就可以看到輸出的日誌了,在JITWatch介面中選擇OpenLog選擇日誌,然後點選Open
然後選擇想要檢視的類和對應的方法,即可檢視對應的原始碼、ByteCode、JIT生成的AssemblyCode。
這裡可以看到一個經常提到的volatile欄位的實現,在MacOS x64的實現是在volatile write後新增一個lock指令作為StoreLoad屏障來保證可見性和防止重排序的。更多JMM的內容可以參考我的另一篇文章Java記憶體模型JMM淺析。
https://liuzhengyang.github.io/2017/05/12/javamemorymodel/
【關於投稿】
如果大家有原創好文投稿,請直接給公號傳送留言。
① 留言格式:
【投稿】+《 文章標題》+ 文章連結
② 示例:
【投稿】《不要自稱是程式員,我十多年的 IT 職場總結》:http://blog.jobbole.com/94148/
③ 最後請附上您的個人簡介哈~
看完本文有收穫?請轉發分享給更多人
關註「ImportNew」,提升Java技能