java查看运行代码的汇编指令(含hsdis-arm64.dll文件)

Posted luffy5459

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了java查看运行代码的汇编指令(含hsdis-arm64.dll文件)相关的知识,希望对你有一定的参考价值。

    本文来自bilibili上的Java系列视频,需要额外的工具就是hsdis-arm64.dll文件。工具下载百度网盘链接:https://pan.baidu.com/s/1Q7kvS3a8YYXfaV3_OjNjBg 提取码:fvzm

    普通的Java代码执行,无法看到汇编指令,若要查看,需要下载hsdis动态链接库。一般网上介绍的都是mac下的hsdis.dylib,这里介绍是win10下的dll。

     这个工具需要放在jdk安装目录下的jre/bin目录下。

 

     运行代码的时候指定jdk为jre。

      准备一个Java代码:

package org.example;

public class VolatileVisibilityTest 
    private static volatile boolean initFlag = false;

    public static void main(String[] args) throws InterruptedException 
        new Thread(()->
            System.out.println("waiting data.....");
            while (!initFlag)

            
            System.out.println("=========success.");
        ).start();

        Thread.sleep(2000);

        new Thread(()->prepareData()).start();

    

    public static void prepareData()
        System.out.println("prepare data end.");
        initFlag = true;
    

    这个程序启动两个线程,一个线程依赖全局变量initFlag会做无限循环,直到initFlag发生改变,循环退出。另一个线程启动去尝试修改initFlag。一般认为,程序会依次打印waiting data,prepare data end,success信息,最后退出。实际上,如果不加volatile关键字,这个程序只是打印waiting data,prepare data end,并不会最终终止。

     

    以上代码,如果不加volatile关键字修饰,程序运行结果:

 

    线程运行在不同的CPU上,各自无法感知initFlag变量发生了改变,所以线程会挂住,一直在等待initFlag发生变化。

     当代码加上volatile关键字,程序运行结果如下所示:

 

    程序经历2秒之后,最终initFlag发生改变,所有线程均感知到,并退出while循环,打印success。最后主线程退出。

    idea下,点击Edit Configurations,弹出框中设置环境以及虚拟机参数:

 

虚拟机参数完整内容:

-server 
-Xcomp 
-XX:+UnlockDiagnosticVMOptions
-XX:+PrintAssembly
-XX:CompileCommand=compileonly,*VolatileVisibilityTest.prepareData

 运行结果截图:

 

   

volatile缓存可见性实现原理:

底层实现主要是通过汇编lock前缀指令,它会锁定这块内存区域的缓存,然后写入主内存。

IA-32和intel64架构软件开发者手册对lock指令的解释:

1)会将当前处理器缓存行的数据立即写回到系统内存

2)写回内存的操作会引起其他CPU缓存了该内存地址的数据无效(缓存一致性协议MSEI)

3) 提供内存屏障功能,使lock前后指令不能重排序


 

   通过上面的汇编指令查看工具,最后运行加了volatile关键字的代码就如前面那样,出现很多汇编指令。并且程序顺利终止。在大量的汇编指令中,我们可以看到如下片段:

 这个lock指令就是前面提到的volatile底层实现原理,他通过lock前缀指令锁定该内存,发生改变之后,立即写入主内存,其他缓存了该内存地址的CPU工作内存会失效,而需要读取主内存中的变量,所以程序最终按照预期完成所有操作并退出。

以上是关于java查看运行代码的汇编指令(含hsdis-arm64.dll文件)的主要内容,如果未能解决你的问题,请参考以下文章

配置VM Options查看Java代码的汇编指令

配置VM Options查看Java代码的汇编指令

配置VM Options查看Java代码的汇编指令

查看Java代码对应的汇编指令又一利器,JITWatch 转

多线程&高并发查看Java代码对应的汇编指令教程

Java代码是怎么运行的