为了屏蔽掉各种硬件核操作系统的内存访问差异,以实现Java程序在各种平台下达到一致的并发效果,JVM中定义了JMM。
JMM:一种规范,规范了JVM与计算机内存是如何协同工作的。它规定了一个线程如何和核实可以看到由其他线程修改过的
共享变量的值,以及在必须时如何同步地访问共享变量。
Heap:堆,运行时的数据区,由垃圾回收来负责,可以动态分配内存大小(导致存取速度比较慢一些),
所以生存期不必事先告诉编译器,垃圾回收器会自动收走不在使用的数据。
Stack:栈,存取速度比堆要快,仅次于计算机里面的内存器,栈的数据可以共享(但是栈中的数据的大小和
生存期必须是确定的,缺乏灵活性,只存访一些基本的变量(short,int,byte,float,double,long,
char等等)),
JMM要求调用栈和本地变量存访在线程栈上(Thread Stack),对象存访在堆上。
例如一个对象的引用存访在线程栈上,对象本身存访在堆上,
一个对象的成员变量可能随着对象存访在堆上,不管这个成员变量是原始类型还是引用类型,静态成员变量跟随
类的定义一起存访在Heap上。
存访在Heap的对象可以被所持有这个对象的线程所访问,同样可以访问这个对象的成员的变量。
如果两个线程同时调用同一个对象的同一个方法,他们都将会访问这个对象的成员变量,但是每个线程都拥有了这个
成员变量的私有拷贝。
计算机硬件架构图示:
两个cpu,有些CPU是多核,从而可以同时运行多个线程。
CPU Registers(CPU寄存器,每个CPU包含一系列的寄存器),CPU内存的基础,CPU在寄存器上执行计算操作的速度
远大于在主存中执行的速度,因为CPU访问寄存器的速度远大于主存。
CPU Cache Memory:高速缓存。CPU访问缓存的速度大于主存的速度。
RAN:主存(内存),一个计算机有一个内存,所有CPU可以访问主存。比缓存大得多。
硬件模型架构没有区分线程栈和堆,对于JVM而言,所有得栈和堆都在主内存里面,部分栈和堆出现在CPU寄存器和缓存中。
每个线程都有一个私有得本地内存:Java内存模型得一个抽象得概念,不是真是存在的,涵盖了缓存,写缓冲区,寄存器等。
两个线程要通信必须通主内存。