乱序执行
乱序:在不影响最终结果的情况下(单线程前后两条指令没有关联),CPU执行指令不一定是顺序的。充分利用cpu
对象的创建过程:
- new:申请一块内存,成员变量设为默认值(半初始化状态)
- 特殊调用
,赋初始值 - t和new T()相关联
注:
- duplicate new完之后在栈帧里面存了一个引用,指向m=8这个对象,并不是本地变量表中的t。dup就是在上面再复制一份这个栈中的内容
- invokespecial会消耗一个值,把它弹出来,把它指向的对象,调用它的构造方法。这时候栈中只剩一个了。
只有在执行了invokespecial(特殊调用),执行了构造方法之后,m才会变成8。 - astore_1的意思是把剩下的一个弹出来赋值给局部变量表的第一个位置。结束后,t才会指向m=8
注:局部变量表的第0个位置是this
禁止乱序
volatile可以禁止指令重排序
volatile并不是用原语来实现,用的是lock指令(锁屏障)
CPU层面:Intel有序性的保障就是原语(sfence,Ifence,mfence)或者锁总线。
注:硬件层面来讲,使用原语效率高于lock指令。但Intel CPU上有这三条原语,别的上不一定有。但这条lock指令,很多CPU都有。所以JVM在实现的时候(或者说是Hotspot),并没有根据不同CPU设计不同原语来执行,而是就用了一条lock指令来实行。
而在JVM层面:8个原则,4个内存屏障(LL LS SL SS)
所谓的JVM实现和这个实现不是一个概念(JVM实现是虚拟机规范层面的,与硬件无任何关系)
![在这里插入图片描述](https://img-blog.csd nimg.cn/20200921174528494.png?x-oss-process=image/watermark,type_ZmFuZ3poZW5naGVpdGk,shadow_10,text_aHR0cHM6Ly9ibG9nLmNzZG4ubmV0L3dlaXhpbl80MzQ4MjI3OQ==,size_16,color_FFFFFF,t_70#pic_center)
内存屏障:什么时候上面执行完了下面才能执行。
合并写
write combining buffer
一般4字节
由于ALU速度太快,所以在写入L1的同时,写入一个WC Buffer,满了之后再直接更新到L2