背景
JVM 有 HotSpot引擎可以对热代码路径进行有效的 JIT优化,大幅度提升计算密集代码的性能。默认一个方法至少被调用10k次以上才可能被JIT优化。
查看JIT工作情况
Java代码
public class VolatileBarrierExample {
long a;
volatile long v1=1;
volatile long v2=1;
void readAndWrite(){
long j=v1;
long i=v2;
a=i+j;
v1=i+1;
long v=v1;
v2=j*2;
}
public static void main(String[] args){
final VolatileBarrierExample ex=new VolatileBarrierExample();
for(int i=0;i<50000;i++)
ex.readAndWrite();
}
}
java -XX:+PrintCompilation VolatileBarrierExample
输出:
VM option '+PrintCompilation'
242 1 VolatileBarrierExample::readAndWrite (40 bytes)
249 1 % VolatileBarrierExample::main @ 10 (27 bytes)
用如下命令行可以更多地了解内联优化的实际情况以及优化发生的级别:
java -XX:+PrintCompilation -XX:+UnlockDiagnosticVMOptions -XX:+PrintInlining -XX:+TieredCompilation VolatileBarrierExample
环境说明:
1. CPU:Intel i7
2. 操作系统:Ubuntu 12.04-amd64
3. JDK:openjdkversion "1.7.0-internal-fastdebug",我使用的是fastdebug版本,可以直接使用openjdk。
4. hsdis 下载地址:https://kenai.com/projects/base-hsdis/downloads,也可自行下载源代码编译,将hsdis-*.so放在目录$JAVA_HOME/jre/lib/amd64/server下.
运行命令:
java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly VolatileBarrierExample
产生的汇编代码
VM option '+UnlockDiagnosticVMOptions'
VM option '+PrintAssembly'
OpenJDK 64-Bit Server VM warning: PrintAssembly is enabled; turning on DebugNonSafepoints to gain additional output
Loaded disassembler from hsdis-amd64.so
Decoding compiled method 0x00007fae110f5890:
Code:
[Disassembling for mach='i386:x86-64']
[Entry Point]
[Constants]
# {method} 'readAndWrite' '()V' in 'VolatileBarrierExample'
# [sp+0x20] (sp of caller)
0x00007fae110f59c0: mov 0x8(%rsi),%r10d
0x00007fae110f59c4: cmp %r10,%rax
0x00007fae110f59c7: jne 0x00007fae110cd920 ; {runtime_call}
0x00007fae110f59cd: nop
0x00007fae110f59ce: nop
0x00007fae110f59cf: nop
[Verified Entry Point]
0x00007fae110f59d0: push %rbp
0x00007fae110f59d1: sub $0x10,%rsp
0x00007fae110f59d5: nop ;*synchronization entry
; - VolatileBarrierExample::readAndWrite@-1 (line 13)
0x00007fae110f59d6: mov 0x18(%rsi),%r10 ;*getfield v1
; - VolatileBarrierExample::readAndWrite@1 (line 13)
0x00007fae110f59da: mov 0x20(%rsi),%r11 ;*getfield v2
; - VolatileBarrierExample::readAndWrite@6 (line 14)
0x00007fae110f59de: mov %r10,%r8
0x00007fae110f59e1: add %r11,%r8
0x00007fae110f59e4: mov %r8,0x10(%rsi)
0x00007fae110f59e8: shl %r10
0x00007fae110f59eb: add $0x1,%r11
0x00007fae110f59ef: mov %r11,0x18(%rsi)
0x00007fae110f59f3: mov %r10,0x20(%rsi) ;*putfield v2
; - VolatileBarrierExample::readAndWrite@36 (line 18)
0x00007fae110f59f7: add $0x10,%rsp
0x00007fae110f59fb: pop %rbp
0x00007fae110f59fc: test %eax,0xa6875fe(%rip) # 0x00007fae1b77d000
; {poll_return}
……….
如果只查看某个方法产生的汇编代码,可以使用命令:
java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*VolatileBarrierExample.readAndWrite VolatileBarrierExample
如果运行命令是出现此错误:
Could not load hsdis-amd64.so; library notloadable; PrintAssembly is disabled
可以设置
export LD_LIBRARY_PATH=$JAVA_HOME/jre/lib/amd64/server/
参考资料:
1. http://chaoslawful.info/archives/387
2. https://wikis.oracle.com/display/HotSpotInternals/PrintAssembly