JVM内存结构 vs JMM内存模型 vs JAVA对象模型
JVM内存结构
JAVA对象模型
JAVA对象自身的存储模型。JVM会给这个类创建一个InstanceKlass,保存在方法区。用来在JVM层展示该Java类。当我们在代码中使用new创建一个对象时,Jvm会创建
一个InstanceOopDesc对象,这个对象中包含了对象头以及实例数据
JMM(Java Memory Model)
Java内存模型是一个规范,如果没有这个规范。不同虚拟机经过重排序之后会导致多线程的执行结果不一样。
重排序:代码执行顺序和代码在java文件中的顺序不一致
好处:提高处理速度
可见性
JMM抽象了主内存和本地内存
- 所有的变量都存储在主内存中,同时每个线程有自己独立的工作内存,工作内存中的变量是主内存中的拷贝
- 线程不能直接读写主内存中的变量,而是只能操作自己工作内存中的数据然后同步到主内存中
- 主内存是多个线程共享的,但是线程间不共享工作内存,所以导致了可见性问题
happens-before原则
在时间上,动作A发生在B之前,B保证能看见A 的。
如果一个操作happens-before另一个操作,那么我们说第一个操作对于另一个操作是可见的
- 单线程
- 锁操作
- volatile
- 线程启动
- 线程join
- 传递性:如果A(hb)B ,B (hb) C,则A(hb)C
- 中断:一个线程如果被中断,则其它线程可以看见检查中断的结果或者InterruptedException
- 构造方法先于finalize
volatile关键字
volatile是一种同步机制,属性不会被线程缓存,始终从主存中读取。可以保证可见性和指令重排序。比synchronized和锁更轻量。不会发生上下文切换等开销大的行为。不具备原子性。不适用于a++。可以使long和double的赋值具备原子性。
常用于
- Boolean 标记的赋值(只能有一个赋值操作,因为这样是原子性的不能依赖于其它操作)。
- 刷新之前变量的触发器功能
原子性
一系列的操作要么都成功要么都失败。
Java常见的原子操作
- 所有基本类型和引用类型的赋值操作(long,double除外)
- juc包中的所有类原子操作
https://naotu.baidu.com/file/60a0bdcaca7c6b92fcc5f796fe6f6bc9?token=bcdbae34bb3b0533