侧边栏壁纸
博主头像
Sir丶雨轩博主等级

一个90的萌新码农,热爱编程热爱生活 编程交流群:875477818

  • 累计撰写 48 篇文章
  • 累计创建 81 个标签
  • 累计收到 0 条评论

目 录CONTENT

文章目录

关于java 虚拟机层面上的可见性

Sir丶雨轩
2020-07-02 / 0 评论 / 1 点赞 / 86 阅读 / 1,945 字 / 正在检测是否收录...
温馨提示:
本文最后更新于 2021-12-23,若内容或图片失效,请留言反馈。部分素材来自网络,若不小心影响到您的利益,请联系我们删除。

首先我们来看一段如下代码

public  class VisibilityDemo {

public  static  class VisibilityThread extends Thread {

private  boolean stop;

@Override

public  void  run()  {

int i = 0;

while  (!stop)  {

               i++;

}

           System.out.println("finish loop,i=" \+ i);

}

public  void  stopLt()  {

stop = true;

}

public  boolean  getStop()  {

return stop;

}

}

public  static  void  main(String\[\] args)  throws InterruptedException {

VisibilityThread v = new  VisibilityThread();

       v.start();

       Thread.sleep(1000);

       v.stopLt();

       Thread.sleep(2000);

       System.out.println("finish main");

       System.out.println(v.getStop());

}

}

按照正常的逻辑 循环肯定是能结束的,但实际上我们运行之后发现,循环是无法停止的

我们反汇编程序看到如下的情况, 如何查看反汇编代码在博客内有相应文章


0x0000000002e2a120: mov     dword ptr \[rsp+0ffffffffffffa000h\],eax

0x0000000002e2a127: push    rbp

0x0000000002e2a128: sub     rsp,20h           ;*synchronization entry

; \- package.VisibilityDemo$VisibilityThread::run@-1  (line 13)

0x0000000002e2a12c: mov     r10,rdx

// 获取stop的值放入 ebp寄存器

0x0000000002e2a12f: movzx   ebp,byte ptr \[rdx+178h\] ;*getfield stop

; \- package.VisibilityDemo$VisibilityThread::run@3  (line 14)

// 测试 stop的值是否为true

0x0000000002e2a136: test    ebp,ebp

// 如果测试通过 跳转至 2e2a14b 进行打印输出

0x0000000002e2a138: jne 2e2a14bh          ;*ifne

; \- package.VisibilityDemo$VisibilityThread::run@6  (line 14)

// 不满足条件 进入循环体

0x0000000002e2a13a: mov     r11d,1h ; OopMap{r10=Oop off=64}

                                               ;*goto

; \- package.VisibilityDemo$VisibilityThread::run@12  (line 15)

// 这个test 是jvm的检查点

0x0000000002e2a140: test    dword ptr \[960000h\],eax  ;*goto

; \- package.VisibilityDemo$VisibilityThread::run@12  (line 15)

 ;  {poll}

// i++

0x0000000002e2a146: inc     r11d              ;*iinc

; \- package.VisibilityDemo$VisibilityThread::run@9  (line 15)

// 无条件跳转至2e2a140

0x0000000002e2a149: jmp 2e2a140h

0x0000000002e2a14b: mov     edx,0ffffff65h

0x0000000002e2a150: mov     qword ptr \[rsp\],r10

0x0000000002e2a154: nop

0x0000000002e2a157: call    2d557a0h          ; OopMap{\[0\]=Oop off=92}

                                               ;*ifne

; \- package.VisibilityDemo$VisibilityThread::run@6  (line 14)

;  {runtime_call}

分析以上汇编代码,我们得到一个结论

这段Java代码被jvm优化成了类似于如下代码的结构


if(!stop){

while(true){

             i++;

}

}
1

评论区