一、多级缓存
现代CPU已经是多核处理器居多,加上主存的速度没有CPU快,很多时候,CPU需要等待主存。多级缓存的作用就是一个高速缓存区,来缓解这种速度上的差异。
在程序执行中,主存中的数据可以放在高速缓存区中,让CPU去执行。
但是高速缓存区空间较小,它的空间远远小于主存。缓存区就变成存放常用数据的存储区了。
二、多级缓存一致性协议:MESI
此处参考的资料:https://blog.csdn.net/muxiqingyang/article/details/6615199
缓存中的数据的四种状态:
三、CUP乱序优化
CPU为了优化代码的执行效率会对代码的执行顺序重新排序,这样会导致多核CPU共享某一个数据出现读取脏数据的现象。
四、JMM(java memory model,中文:java内存模型)
参考的资料:
https://www.cnblogs.com/whgw/archive/2011/09/29/2194997.html
https://www.cnblogs.com/lewis0077/p/5143268.html
(1)java内存的堆中存放的是运行时的数据(new创建的对象和数组),相对来说运行效率较低。堆是JVM所管理的内存中最大的一块,是被所有Java线程锁共享的,不是线程安全的。
(2)栈是编译好的数据,相对来说不会变化(在函数中定义的一些基本类型的变量和对象的引用变量都是在函数的栈内存中分配)。Java栈总是与线程关联在一起的,每当创建一个线程,JVM就会为该线程创建对应的Java栈,在这个Java栈中又会包含多个栈帧(Stack Frame)。每运行一个方法就创建一个栈帧
,每个栈帧会含有一些局部变量、操作栈和方法返回值等信息。当这个栈帧中所有指令都完成时,这个栈帧被移除Java栈
(3)下面的图更详细的描述了数据区的所有的区域
PC寄存器/程序计数器:为了线程切换后能恢复到正确的执行位置,每个线程都需要有一个独立的程序计数器,各个线程之间计数器互不影响,独立存储
,我们称这类内存区域为“线程私有”的内存,这在某种程度上有点类似于“ThreadLocal”,是线程安全的。
(4)方法区存放了要加载的类的信息(名称、修饰符等)、类中的静态常量、类中定义为final类型的常量、类中的Field信息、类中的方法信息。不像Java堆中其他部分一样会频繁被GC回收,方法区也是堆中的一部分,就是我们通常所说的Java堆中的永久区 Permanet Generation。
(5)本地方法栈:本地方法栈和Java栈所发挥的作用非常相似,区别不过是Java栈为JVM执行Java方法服务,而本地方法栈为JVM执行Native方法服务。本地方法栈也会抛出StackOverflowError和OutOfMemoryError异常。
硬件内存模型:如果CPU需要将数据刷新到主存中,首先需要将数据刷新到缓存区中,缓存区以后再寻找合适的时间节点将数据刷新到主存中。
两个线程执行过程:
变量被使用的过程: lock -> read -> load -> use -> assign -> store -> write -> unlock
补充:只当read将变量从主内存中读到工作内存中,然后其他程序才可load该变量。