为了更好地理解Java代码,内部具体是怎么运行,我们常常会通过反汇编来查看汇编代码。Java本身也是提供这个支持的。
通过开启以下两个属性即可(关于具体参数配置,可以查看这里)
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly
实战
实验环境
mac os 10.11.4
jdk1.8.0_31
M3.java
public class M3 {
static int a, b;
public static void main(String[] args) {
a = b + 1;
b = 1;
}
}
javac M3.java
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly M3
按照我们预想的结果会看一大串汇编代码, 但是却报出了一个异常,如下
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
经过Google之后得知, 这种反汇编操作是需要插件支持的, 在mac系统下需要安装一个hsdis-amd64.dylib的插件。在网上找了一个,地址在这里。
下载下来后,将其放置到你的jre lib目录下即可。
在我的系统上命令如下,
sudo mv ./hsdis-amd64.dylib /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib
然后再运行
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly M3
即可看见汇编代码, 如下
Loaded disassembler from /Library/Java/JavaVirtualMachines/jdk1.8.0_31.jdk/Contents/Home/jre/lib/hsdis-amd64.dylib
Decoding compiled method 0x0000000107e1ce90:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Constants]
# {method} {0x000000011bb8ed80} 'charAt' '(I)C' in 'java/lang/String'
# this: rsi:rsi = 'java/lang/String'
# parm0: rdx = int
# [sp+0x40] (sp of caller)
0x0000000107e1d000: mov 0x8(%rsi),%r10d
0x0000000107e1d004: shl $0x3,%r10
0x0000000107e1d008: cmp %rax,%r10
0x0000000107e1d00b: jne 0x0000000107d64b60 ; {runtime_call}
0x0000000107e1d011: data32 data32 nopw 0x0(%rax,%rax,1)
0x0000000107e1d01c: data32 data32 xchg %ax,%ax
[Verified Entry Point]
0x0000000107e1d020: mov %eax,-0x14000(%rsp)
.........以下省略5000行
问题
这里有一个问题, 汇编代码有5000多行,明显不是我M3.java的代码,具体原因未知