原创

如何查看volatile汇编代码

一、Linux 环境:

Linux localhost 2.6.32-696.el6.x86_64 #1 SMP Tue Mar 21 19:29:05 UTC 2017 x86_64 x86_64 x86_64 GNU/Linux

二、安装 hsdis

1.从如下地址下载 hsdis-amd64.so 文件并拷贝到路径{JAVA_HOME}/jre/lib/amd64/server 下。

http://lafo.ssw.uni-linz.ac.at/hsdis/att/

2.查看是否 OK

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly -version

三、编写 java 文件

Test.java

public class Test {
	public volatile long sum = 0;

	public int add(int a, int b) {
		int temp = a + b;
		sum += temp;
		return temp;
	}

	public static void main(String[] args) {
		Test test = new Test();

		int sum = 0;

		for (int i = 0; i < 1000000; i++) {
			sum = test.add(sum, 1);
		}

		System.out.println("Sum:" + sum);
		System.out.println("Test.sum:" + test.sum);
	}
}

四、将 java 文件编译成 class 文件

javac Test.java

五、将 class 生成汇编代码

查看 Test 所有方法的汇编代码

java -XX:+UnlockDiagnosticVMOptions -XX:+PrintAssembly Test >gameboys

查看 add 方法的汇编代码

java -XX:+UnlockDiagnosticVMOptions -XX:CompileCommand=print,*Test.addTest

六、查看汇编代码

vim gameboys

七、从上面的代码,我们可以找到 volatile 对应的指令集为:

  0x00007f14bd10b59a: lock addl $0x0,(%rsp)     ;*putfield sum
                                                ; - Test::add@12 (line 6)

他对应上面 Test.java 的 sum += temp;

总结:

我们可以看到,sum 是使用了 volatile 关键字修饰的成员变量,在运算的时候,使用到了 lock 前缀的内存屏障指令,他就能提供禁止指令重排序和可见性的保证。

正文到此结束