當前環境:jdk1.8,win10,64位
打印Java彙編指令
使用hsdis工具打印彙編指令,可以自行編譯或者下載已編譯好的dll或so文件,並將文件拷貝至jdk安裝目錄下的bin/server或者bin/client,例如:D:\Program Files\Java\jdk1.8.0_131\bin\server\hsdis-amd64.dll
windows下編譯教程:https://dropzone.nfshost.com/hsdis/
執行Java命令增加如下參數,參考:https://wiki.openjdk.java.net/display/HotSpot/PrintAssembly
或者可以將參數放在標誌文件中並通過參數指定標誌配置文件:-XX:Flags=myhotspotrc.txt
-server
-XX:+UnlockDiagnosticVMOptions // 由於下面的參數屬於診斷參數,所以在使用之前需要打開UnlockDiagnosticVMOptions參數
-XX:+TraceClassLoading
-XX:+PrintAssembly // 爲字節碼與本地方法打印彙編代碼print assembly code for bytecoded and native methods
-XX:+LogCompilation
-XX:+DebugNonSafepoints
-XX:LogFile=VisibilityWithoutVolatile.log // 指定日誌文件
-Xcomp // JVM在第一次執行時便會把所有的字節碼編譯成本地代碼
-XX:CompileCommand=compileonly,*VisibilityWithoutVolatile.* 僅編譯指定類的某個方法,星號代表所有方法
// 不需要加該參數:-XX:CompileCommand=dontinline,*VisibilityWithoutVolatile.* 內聯問題,可以指定不對某些方法進行jit編譯,跳過有問題方法的編譯 // Allow use of -XX:CompileCommand=dontinline to exclude problematic methods
使用jitwatch分析日誌
使用方法參考:https://github.com/AdoptOpenJDK/jitwatch
博主是通過mvn引入pom依賴,然後直接執行jitwatch的main方法開始使用。源碼地址:https://github.com/GallantKong/jitwatch-example
import org.adoptopenjdk.jitwatch.launch.LaunchUI;
/**
* @author 會灰翔的灰機
* @date 2019/10/30
*/
public class JITWatchMain {
public static void main(String[] args) {
LaunchUI.main(args);
}
}
--pom.xml
<dependency>
<groupId>com.chrisnewland</groupId>
<artifactId>jitwatch-parent</artifactId>
<version>1.1.5</version>
<type>pom</type>
</dependency>
<dependency>
<groupId>com.chrisnewland</groupId>
<artifactId>jitwatch</artifactId>
<version>1.1.5</version>
</dependency>
<dependency>
<groupId>com.chrisnewland</groupId>
<artifactId>jitwatch-ui</artifactId>
<version>1.1.5</version>
</dependency>
配置jitwatch
源碼文件目錄
字節碼文件目錄
問題
不顯示源碼
不顯示源碼問題主要因爲源碼路徑配置不對,需要配置到源碼的具體所在目錄,jitwatch不會自動遞歸目錄查找源碼
不顯示彙編代碼
全部顯示沒有彙編代碼,或者部分顯示有彙編代碼,部分沒有。案例如圖:顯示不是JIT編譯代碼
- jvm在方法執行達到一定的熱度纔會將代碼編譯成特定平臺的彙編語言執行,使用-Xcomp參數指定jvm在第一次執行時把所有的字節碼編譯成本地代碼
- 大型方法會在執行到限制時纔會執行編譯。所以平時不建議大家方法寫的過大跟該參數的默認啓用有些關係
-XX:+DontCompileHugeMethods // 打開不編譯巨大的方法,直至達到限制
-XX:HugeMethodLimit=8000 // HotSpot VM默認不會JIT編譯字節碼大小超過8000字節的方法
方法彙編代碼顯示級別不同
- 如下圖:run方法顯示級別爲#3(C2/OSR/level4);main方法提示級別爲#2(C2/level4)