Java内存模型(JMM)详解(1)

简介: Java内存模型(JMM)详解

一、为什么要有内存模型

  • 在现代多核处理器中,每个处理器都有自己的缓存,需要定期的与主内存进行协调。
  • 想要确保每个处理器在任意时刻知道其他处理器正在进行的工作,将需要很大的开销,且通常是没必要的。

1.1 硬件的效率与一致性

1、 由于计算机的存储设备与处理器的运算能力之间有几个数量级的差距,所以现代计算机系统都不得不加入一层读写速度尽可能接近处理器运算速度的高速缓存(cache)来作为内存与处理器之间的缓冲:将运算需要使用到的数据复制到缓存中,让运算能快速进行,当运算结束后再从缓存同步回内存之中没这样处理器就无需等待缓慢的内存读写了。


2、多个处理器运算任务都涉及同一块主存,需要一种协议可以保障数据的一致性,这类协议有MSI、MESI、MOSI及Dragon Protocol等。Java虚拟机内存模型中定义的内存访问操作与硬件的缓存访问操作是具有可比性的。


3、基于高速缓存的存储交互很好地解决了处理器与内存的速度矛盾,但是引入了一个新的问题:缓存一致性(Cache Coherence)。在多处理器系统中,每个处理器都有自己的高速缓存,而他们又共享同一主存,下面会介绍这个问题

屏幕快照 2022-05-10 下午1.42.57.png

二、CPU和缓存一致性

2.1 为什么需要CPU cache

因为CPU的频率太快了,快到主存跟不上,这样在处理器时钟周期内,CPU常常需要等待主存,浪费资源。CPU往往需要重复处理相同的数据、重复执行相同的指令,如果这部分数据、指令CPU能在CPU缓存中找到,CPU就不需要从内存或硬盘中再读取数据、指令,从而减少了整机的响应时间,所以cache的出现,是为了缓解CPU和内存之间速度的不匹配问题(结构:cpu -> cache -> memory)


屏幕快照 2022-05-10 下午1.43.36.png

在程序执行的过程中就变成了:


当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU

进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高

速缓存中的数据刷新到主存当中。


在Intel官网上产品-处理器界面内对缓存的定义为:CPU高速缓存是处理器上的一个快速记忆区域。英特尔智能高速缓存(SmartCache)是指可让所有内核动态共享最后一级高速缓存的架构。这里就提及到了最后一级高速缓存的概念,即为CPU缓存中的L3(三级缓存),那么我们继续来解释一下什么叫三级缓存,分别又是指哪三级缓存。

屏幕快照 2022-05-10 下午1.43.47.png

2.2 三级缓存(L1、L2、L3)


三级缓存(L1一级缓存、L2二级缓存、L3三级缓存)都是集成在CPU内的缓存

它们的作用都是作为CPU与主内存之间的高速数据缓冲区

L1最靠近CPU核心,L2其次,L3再次

运行速度方面:L1最快、L2次快、L3最慢

容量大小方面:L1最小、L2较大、L3最大

CPU会先在最快的L1中寻找需要的数据,找不到再去找次快的L2,还找不到再去找L3,L3都没有那就只能去内存找了。

单核CPU只含有一套L1,L2,L3缓存;如果CPU含有多个核心,即多核CPU,则每个核心都含有一套L1(甚至和L2)缓存,而共享L3(或者和L2)缓存。

单CPU双核的缓存结构:

屏幕快照 2022-05-10 下午1.44.29.png

在单线程环境下,cpu核心的缓存只被一个线程访问。缓存独占,不会出现访问冲突等问题

在多线程场景下,在CPU和主存之间增加缓存,就可能存在缓存一致性问题,也就是说,在多核CPU中,每个核的自己的缓存中,关于同一个数据的缓存内容可能不一致,这也就是我们上面提到的缓存一致性的问题


屏幕快照 2022-05-10 下午1.44.34.png


2.3 乱序执行优化


从java源码到最终实际执行的指令序列,会经历下面3种重排序:

屏幕快照 2022-05-10 下午1.44.38.png


重排序的现象:


a=10,b=a 这一组 b依赖a,不会重排序

a=10,b=50 这一组 a和b 没有关系,那么就有可能被重排序执行 b=50,a=10

cpu和编译器为了提高程序的执行效率会按照一定的规则允许指令优化,不影响单线程程序执行结果,但是多线程就会影响程序结果

屏幕快照 2022-05-10 下午1.44.42.png

目录
相关文章
|
1天前
|
Java 程序员 编译器
Java内存模型深度解析与实践优化策略
在多线程编程领域,Java内存模型(Java Memory Model, JMM)是确保并发程序正确性的基石。本文深入探讨JMM的工作原理,结合最新研究成果和实际案例,揭示高效同步策略和避免常见并发缺陷的方法。文章不仅阐述理论,更注重实践,旨在为Java开发者提供全面的内存模型应用指南。
|
1天前
|
Java 程序员
深入理解Java内存模型(JMM)与并发编程
在Java并发编程领域,理解Java内存模型(JMM)是至关重要的。本文旨在通过数据导向的分析、科学严谨的论述和逻辑严密的结构,探讨JMM如何影响并发编程实践。我们将从JMM的基本概念出发,逐步深入到并发编程中的具体应用,包括同步机制、volatile关键字的作用以及线程间的通信。本文将引用权威研究与实验证据,结合经典理论,为读者提供全面的JMM知识框架,以促进对Java并发编程深层次的理解。
|
2天前
|
设计模式 缓存 Java
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
Java设计模式:享元模式实现高效对象共享与内存优化(十一)
|
1天前
|
存储 安全 Java
Java内存模型:你需要知道的一切
Java内存模型:你需要知道的一切
|
1天前
|
Java
Java内存模型之原子性问题
Java内存模型之原子性问题
|
2天前
|
存储 缓存 Java
【Java并发基础】Java内存模型解决有序性和可见性
【Java并发基础】Java内存模型解决有序性和可见性
|
2天前
|
存储 缓存 Java
Java对象内存布局深度解析
Java对象内存布局深度解析
8 0
|
存储 缓存 安全
基于JVM原理、JMM模型和CPU缓存模型深入理解Java并发编程
许多以Java多线程开发为主题的技术书籍,都会把对Java虚拟机和Java内存模型的讲解,作为讲授Java并发编程开发的主要内容,有的还深入到计算机系统的内存、CPU、缓存等予以说明。实际上,在实际的Java开发工作中,仅仅了解并发编程的创建、启动、管理和通信等基本知识还是不够的。
3938 0
|
1天前
|
监控 安全 算法
如何有效地处理Java中的多线程
如何有效地处理Java中的多线程
|
2天前
|
Java 调度
Java多线程编程与并发控制策略
Java多线程编程与并发控制策略