1.cpu基本构成
- program conter 程序计数器 记录当前指令地址
- register 寄存器 暂时存储cpu使用到的数据
- ALU arithmetic & logic unit 运算单元
- CU control unit 控制单元 中断
- MMU memory manager unit 内存管理单元 程序虚拟内存与真实物理内存地址转换
- cache L1 L2 L3级别缓存
2.缓存一致性协议
inter 缓存行 64KB
JDK避免频繁修改的两个属性属于同一个缓存行
@Contended -XX:-RestrictContended
- modified 被修改的 缓存行数据已经被更改,但还未写回内存当中
- exclusive 独享的 缓存行被该cpu一个人使用,还没有做任何修改
- shared 共享的 多个cpu 同时访问该数据,还没有做任何修改
- invalid 无效的 缓存行已经被其他cpu修改
exclusive -- 另一个cpu参与了 -- shared -- 一个cpu修改了
-- 发起修改的cpu 变成了 modified
-- 被修改的cpu 变成了 invalid
3.禁止cpu指令重排
-
cpu interl mfence lfence sfence lock 锁总线
-
jvm 8个hanppens-before原则 4个内存屏障 (LL LS SL SS)
-
jvm 单线程 执行结果保持一致
-
程序次序规则:在一个单独的线程中,按照程序代码的执行流顺序,(时间上)先执行的操作happen—before(时间上)后执行的操作
-
管理锁定规则:一个unlock操作happen—before后面(时间上的先后顺序,下同)对同一个锁的lock操作
-
volatile变量规则:对一个volatile变量的写操作happen—before后面对该变量的读操作
-
线程启动规则:Thread对象的start()方法happen—before此线程的每一个动作
-
线程终止规则:线程的所有操作都happen—before对此线程的终止检测,可以通过Thread.join()方法结束、Thread.isAlive()的返回值等手段检测到线程已经终止执行
-
线程中断规则:对线程interrupt()方法的调用happen—before发生于被中断线程的代码检测到中断时事件的发生
-
对象终结规则:一个对象的初始化完成(构造函数执行结束)happen—before它的finalize()方法的开始
-
传递性:如果操作A happen—before操作B,操作B happen—before操作C,那么可以得出A happen—before操作C
- LoadLoad屏障:对于这样的语句Load1; LoadLoad; Load2,在Load2及后续读取操作要读取的数据被访问前,保证Load1要读取的数据被读取完毕
- StoreStore屏障:对于这样的语句Store1; StoreStore; Store2,在Store2及后续写入操作执行前,保证Store1的写入操作对其它处理器可见
- LoadStore屏障:对于这样的语句Load1; LoadStore; Store2,在Store2及后续写入操作被刷出前,保证Load1要读取的数据被读取完毕
- StoreLoad屏障:对于这样的语句Store1; StoreLoad; Load2,在Load2及后续所有读取操作执行前,保证Store1的写入对所有处理器可见。它的开销是四种屏障中最大的。在大多数处理器的实现中,这个屏障是个万能屏障,兼具其它三种内存屏障的功能
synchronize
- 获得互斥锁
- 清空工作内存
- 从主内存拷贝变量的最新副本到工作内存
- 执行代码
- 将更改后的共享变量的值刷新到主内存中
- 释放互斥锁
volatile
在每个volatile写操作前插入StoreStore屏障,在写操作后插入StoreLoad屏障
在每个volatile读操作前插入LoadLoad屏障,在读操作后插入LoadStore屏障
线程写volatile变量的过程:
-
- 改变线程工作内存中volatile变量副本的值
- 将改变后的副本的值从工作内存刷新到主内存
线程读volatile变量的过程:
-
- 从主内存中读取volatile变量的最新值到线程的工作内存中
- 从工作内存中读取volatile变量的副本
public class Demo { private static Demo demo = new Demo(); private Demo(){} public static Demo getInstance(){return demo;} }
public class Demo { private static class InnerDemo { private static final Demo demo = new Demo(); } private Demo(){} public static Demo getInstance(){return InnerDemo.demo} }
public enum Demo { INSTANCE; }
public class Demo { private volatile Demo demo; private Demo(){} public static Demo getInstance(){ if (null != demo){ synchronize(Demo.class){ if( null != demo ){ demo = new Demo(); } } } return demo; } }
4.NUMA
Non Uniform Memory Access
分配内存会优先分配该线程所在CPU的最近内存
5.OS
- 用户态 ring3
- 内核态 ring0
ring3 请求 ring0 得到内核同意 调用 ring0 接口