Java程式碼如何檢視位元組碼及彙編碼

一品威客01 發表於 2021-01-25

我們知道一個Java類要想被Java虛擬機器載入,必須先生成相應的二進位制檔案,即class檔案,而一個方法或一段程式碼在執行期要麼被解釋執行,要麼被編譯器編譯成彙編碼,編譯執行,那如何去檢視這些轉換後的程式碼呢?

命令 javap

javap -v/-c F.class

javap 可以用命令擴充在ide工具裡,如:

eclipse Run/External Tools 然後點選要檢視的檔案,Run/External Tools/javap

解釋下配置項Name: 命名,如javap

Location: jdk中javap命令的絕對路徑

Working Directory:

工作目錄,可以在Variables裡選擇,

${project_loc} 表示當前所選擇的resource所在的project或正構建的project或所選擇的的絕對路徑

如果當前project已經加入到eclipse的workspace中,也可用 ${workspace_loc}/${project_name}

Arguments:

當前執行檔案相對於Working Directory的路徑

-classpath target/classes: classpath路徑

-v: Javap命令的

${java_type_name}:即當前Java檔案對於的class檔案,Variables裡選擇

eclipse擴充Javap命令 也可以在idea File/Settings/Tools/External Tools中配置:

idea擴充Javap命令 配置完後,右鍵需要檢視的檔案,選擇External Tools/javap -v

檢視彙編碼

首先要下載hsdis-amd64.dll檔案,並將檔案放置在%JAVA_HOME%/jre/bin的server和client目錄下

放置完後,可以 命令測試 java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version

如果輸出PrintAssembly is enabled,說明hsdis-amd64安裝成功

hsdis-amd64安裝 注:有些jdk版本沒有client目錄

然後配置VM

-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*Test.add

idea中檢視彙編碼 解釋下配置項:

java -version -server -Xcomp

虛擬機器一般有兩種模式執行執行程式碼,即解釋模式和編譯模式,預設採用直譯器與其中一個編譯器直接配合的方式工作:混合模式,可以看到Java -version 輸出內容有mixed mode

使用引數“-Xint”強制虛擬機器執行於“解釋模式”(Interpreted Mode)

使用引數“-Xcomp”強制虛擬機器執行於“編譯模式”(CompiledMode)

而HotSpot虛擬機器中內建了兩個即時編譯器

C1 ClientCompiler

C2 Server Compiler

從Java -version 輸出 Java HotSpot(TM) 64-Bit Server VM可以得知,執行於Server模式

-XX:+UnlockDiagnosticVMOptions

開啟虛擬機器的診斷模式,一些引數(如PrintAssembly)在診斷模式下才能使用

-XX:+PrintAssembly

列印即時編譯後的二進位制資訊,即彙編碼

-XX:CompileCommand=compileonly,*Test.add

編譯時接受的指令,這裡compileonly,*Test.add 是指編譯add方法

全能檢視,即可檢視程式碼,同時也可以對照位元組碼和彙編碼

在GitHub中下載jitwatch,點選其目錄下的launchUI,開啟圖形視窗,

config中配置Java檔案所在的專案路徑及classpath路徑

jitwatch Config配置 idea VM 引數

-server -Xcomp -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -XX:CompileCommand=compileonly,*Test.add -XX:+LogCompilation -XX:LogFile=jit1.log

執行後會在classpath下生成jit1.log日誌檔案,點選jitwatch視窗的Open Log匯入日誌檔案,再Staart執行,可以檢視執行的Source,Bytecode,Assembiy