JVM 虚拟机(3)JMM Java内存模型

在学习Java内存模型之前,有几个知识点必须先了解一下。
1. cpu和物理内存的读写速度差会导致什么问题?如何解决?
2. 计算机内存模型是什么?为什么需要计算机内存模型?
最后再了解:
3. 什么是JMM?

cpu和物理内存的读写速度差会导致什么问题?如何解决?

计算机的每条指令,都是通过cpu来执行的,执行过程中,大多情况下都需要与内存打交道。在早些时候,cpu的运算速度和内存的运算速度相差无几,于是两者过的相安无事。但是随着cpu的不断发展,cpu的计算速度远远超过了内存。所以就导致每次cpu都要在等待内存上耗费很长时间。
于是就诞生了高速缓存这一中间人,其实也就是我们平常所说的缓存。它的作用时:在cpu进行计算时,先将所需的数据从内存拷贝一份到高速缓存中,cpu在获取数据时,就直接从缓存中获取,写数据的时候,也可以直接往高速缓存中写入。运算结束时,再将缓存中的数据刷新到内存中即可。
举个例子,有一份工作需要张三和李四配合进行,张三负责工作前半部分,李四负责工作后半部分,起初两者都是新手,干活速度不相上下,于是这个工作刚好能衔接上。但是随着时间的积累,李四的干活速度越来越快(cpu在升级),而张三的干活速度依旧如此(内存的速度在原地踏步),所以导致李四干完了,需要浪费很多时间在等待张三上。 所以呢,公司为了这个问题,又招了王五作为协调员,又招了n个张三来做底层工作。协调员这边负责将n个张三完成的工作缓存起来(高速缓存的作用),等到李四开始工作时,直接与协调员对接即可。

计算机内存模型是什么?为什么需要计算机内存模型?

咱们这先提一下计算机缓存,计算机缓存分一级缓存(L1 cache)、二级缓存(L2 cache)、三级缓存(L3 cache)。当然不是所有计算机都配有这三级,也是看配置的。
在cpu执行时,会先从一级缓存中获取数据,如果没有再从二级缓存中获取数据,如果还是没有,则会去三级缓存或者内存中获取数据。
对于多核cpu来说,每个核都会有自己的一级缓存,二级缓存可能是共享的,也可能是单独的,而三级缓存一般来说都是共享的。


计算机三级缓存

说完了计算机缓存,咱们再聊一下计算机的单线程和多线程,单核与多核的问题,这将对计算机内存模型产生至关重要的影响。
我们可以分下面几种情况来考虑:

  1. 单线程(无论单核还是多核)
    单线程执行,就不用考虑资源竞争的问题了,反正数据都是按顺序读的,按顺序写的,不会存在并发修改等并发问题,这种时候也就不需要对内存数据进行什么保护措施,数据是绝对不可能乱的。

  2. 单核多线程
    单核是可以开启多线程操作的,但不要误以为这是并行,你肉眼看着多个任务同时进行,其实底层操作系统还是按着串行但方式在运行,操作系统是以时间片为单位控制着每个线程的挂起和执行。
    举例来说,比如当下有a、b、c三个线程,操作系统给a分了10个时间片,于是a执行了10个时间片后,就被操作系统挂起了,紧接着又给b分了10个时间片,b执行完后也被挂起了,如此反复,因为一个时间片大概10ms左右,所以以人肉眼的角度来观察多个任务的执行情况,其实是看不出这其实是在串行执行。
    所以,这也解释了,这种情况下,其实也不需要对内存数据做什么保障,串行已经解决了一切脏数据问题。

  3. 多核多线程
    上面也说到了,每个核心,是有自己对一级缓存的,所以当core1上当线程1修改了该内核下当L1缓存后,core2上当线程2修改了该内核下当L1缓存,这时两者当缓存数据就对不上了,如果这时候需要对这份数据进行其它计算,那就会导致计算错误。这其实也就是我们经常说的缓存一致性问题

除了上述多核多线程的情况会导致缓存不一致问题之外,如果考虑硬件方面的话,还有其它情况,我这里就说一点:

  1. 指令重排序
    重排序是指编译器和处理器为了优化程序性能而对指令序列进行重新排序的一种手段。
    假设现在有如下两句代码要执行:
    a = 1; a = 2;
    很明显,先执行a=1a=2,对于a的结果值来说是显然不同的两种情况。当然,在单线程情况下,操作系统会在遵守原有的串行逻辑的语义下,对指令进行重排序,人话来说就是:我不会让你对结果变的!
    但不同处理器和不同线程之间的数据性不会被编译器和处理器考虑到,所以会因此而产生数据不一致的情况。

更详细的文档可参考:https://www.zybuluo.com/kiraSally/note/850631#24-%E9%87%8D%E6%8E%92%E5%BA%8F%E7%9A%84%E6%89%A7%E8%A1%8C%E6%B5%81%E7%A8%8B

那这些问题操作系统怎么解决呢?内存模型!
简单的来说,计算机内存模型定义了两种解决方式:

  1. 内存屏障
  2. 限制处理器做优化

什么是JMM?

  • Java内存模型是一个抽象的概念,并非真实存在。
  • JMM定义了线程和主内存之间的关系:
    1. 线程之间的共享变量存储在主内存中。
    2. 每个线程都有一个私有的本地内存,其中保存了该线程使用到的共享变量的主内存副本拷贝。
  • JMM屏蔽了操作系统和硬件的内存访问差异,所以Java才得意在各个平台上达到访问内存的一致性。
  • 重点:主内存和线程私有的工作内存,与JVM的堆栈不是一回事。主内存应该是指内存条,而工作内存应该是指寄存器和高速缓存。

JMM的核心原则

多线程的原子性、可见性、有序性。
JMM是一种规范,目的是解决由于多线程通过共享内存进行通信时,存在的本地内存数据不一致、编译器会对代码指令重排序、处理器会对代码乱序执行等带来的问题。目的是保证并发编程场景中的原子性、可见性和有序性。

原子性

  • 原子性是指一个操作是不可中断的,即多线程环境下,操作不能被其他线程干扰

可见性

  • 可见性是指当一个线程修改了某一个共享变量的值,其他线程是否能够立即知道该变更
  • Java中普通的共享变量不保证可见性,因为其修改被写入内存的时机是不确定的,多线程并发下很可能出现"脏读"
  • 缓存优化或者硬件优化或指令重排以及编辑器的优化都可能导致一个线程修改不会立即被其他线程察觉
  • Java提供volatile保证可见性:写操作立即刷新到主内存,读操作直接从主内存读取
  • Java同时还可以通过加锁的同步性间接保证可见性:synchronized和Lock能保证同一时刻只有一个线程获取锁并执行同步代码,并在释放锁之后将变量的修改刷新到主内存中

有序性

  • 对于一个线程的执行代码而言,我们总是习惯性认为代码的执行总是从上到下,有序执行,但为了提供性能,编译器和处理器通常会对指令序列进行重新排序
  • 指令重排可以保证串行语义一致,但没有义务保证多线程间的语义也一致,即可能产生"脏读"

参考文章:
https://mp.weixin.qq.com/s/n0U2IJwhT3OAp_EwRdzYIA
https://www.zybuluo.com/kiraSally/note/850631#3happends-before

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 203,362评论 5 477
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 85,330评论 2 381
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 150,247评论 0 337
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 54,560评论 1 273
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 63,580评论 5 365
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 48,569评论 1 281
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 37,929评论 3 395
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 36,587评论 0 258
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 40,840评论 1 297
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 35,596评论 2 321
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 37,678评论 1 329
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 33,366评论 4 318
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 38,945评论 3 307
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 29,929评论 0 19
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 31,165评论 1 259
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 43,271评论 2 349
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 42,403评论 2 342

推荐阅读更多精彩内容