一、当代计算机体系结构
1、当代计算CPU体系
大体上如下
每个CPU有一个共享缓存,名为三级缓存L3
每个CPU有多个核心组成
每个核心有两级缓存,分别叫一级缓存L1,二级缓存L2
一级缓存分两种,分别叫数据缓存(L1 D),指令缓存(L1 i)
CPU肯定是需要和内存交互的,这个过程是少不了的
一个线程肯定是要运行在一个核上的,多个线程可以运行在不同的核上,这个时候,因为缓存的存在,如果没有同步机制,那一个线程修改了缓存的数据,另一个线程也修改了缓存的数据,这个时候这两个线程修改后的数据都需要写入到内存当中,就会出现问题
jvm为了方便,将这些缓存抽象出来,构造了自己的内存模型,即主内存和工作内存的数据交互,即java 内存模型(jmm)
2、jvm 内存结构
当使用java -jar 执行程序的时候,就会启动一个JVM虚拟机
JVM虚拟机的内存结构
jvm会从内存中划分一块内存区域,并规划出几部分,这几部分如下
(1)方法区
(2)堆区
(3)本地方法栈
(4)虚拟机栈
(5)程序计数器
方法区和堆区是线程共享的区域
本地方法栈,虚拟机栈和程序计数器是每个线程私有的区域,也就是每启动一个线程,就会有一个本地方法栈的栈帧和虚拟机栈的栈帧供给线程使用
虚拟机栈和本地方法栈的数据会从堆内存和方法区中进行拷贝
三、jmm内存模型
线程通信有两种方式:共享内存和消息传递
在jvm中,线程通信是通过共享内存消息来得,这也就是为什么需要定义jmm内存模型
Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样底层细节。此处的变量与Java编程时所说的变量不一样,指包括了实例字段、静态字段和构成数组对象的元素,但是不包括局部变量与方法参数,后者是线程私有的,不会被共享。
Java内存模型中规定了所有的变量都存储在主内存中,每条线程还有自己的工作内存(可以与前面讲的处理器的高速缓存类比),线程的工作内存中保存了该线程使用到的变量到主内存副本拷贝,线程对变量的所有操作(读取、赋值)都必须在工作内存中进行,而不能直接读写主内存中的变量。不同线程之间无法直接访问对方工作内存中的变量,线程间变量值的传递均需要在主内存来完成,线程、主内存和工作内存的交互关系如下图所示,和上图很类似。