深入理解Java内存模型

【1】CPU和缓存的一致性

​ 我们应该都知道,计算机在执行程序的时候,每条指令都是在CPU中执行的,而执行的时候,又免不了要和数据打交道。而计算机上面的数据,是存放在主存当中的,也就是计算机的物理内存啦。

​ 刚开始,还相安无事的,但是随着CPU技术的发展,CPU的执行速度越来越快。而由于内存的技术并没有太大的变化,所以从内存中读取和写入数据的过程和CPU的执行速度比起来差距就会越来越大,这就导致CPU每次操作内存都要耗费很多等待时间。

​ 所以,人们想出来了一个好的办法,就是在CPU和内存之间增加高速缓存。缓存的概念大家都知道,就是保存一份数据拷贝。他的特点是速度快,内存小,并且昂贵。

那么,程序的执行过程就变成了:

当程序在运行过程中,会将运算需要的数据从主存复制一份到CPU的高速缓存当中,那么CPU进行计算时就可以直接从它的高速缓存读取数据和向其中写入数据,当运算结束之后,再将高速缓存中的数据刷新到主存当中。

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

【2】处理器优化和指令重排

上面提到在在CPU和主存之间增加缓存,在多线程场景下会存在缓存一致性问题。除了这种情况,还有一种硬件问题也比较重要。那就是为了使处理器内部的运算单元能够尽量的被充分利用,处理器可能会对输入代码进行乱序执行处理。这就是处理器优化

除了现在很多流行的处理器会对代码进行优化乱序处理,很多编程语言的编译器也会有类似的优化,比如Java虚拟机的即时编译器(JIT)也会做指令重排

可想而知,如果任由处理器优化和编译器对指令重排的话,就可能导致各种各样的问题。

解决方法:内存屏障

【3】什么是Java内存模型

内存模型

为了保证共享内存的正确性(可见性、有序性、原子性),内存模型定义了共享内存系统中多线程程序读写操作行为的规范。通过这些规则来规范对内存的读写操作,从而保证指令执行的正确性。

Java内存模型(Java Memory Model,JMM)是java虚拟机规范定义的,用来屏蔽掉java程序在各种不同的硬件和操作系统对内存的访问的差异,这样就可以实现java程序在各种不同的平台上都能达到内存访问的一致性。

​ Java内存模型的主要目标是定义程序中变量的访问规则。即在虚拟机中将变量存储到主内存或者将变量从主内存取出这样的底层细节。需要注意的是这里的变量跟我们写java程序中的变量不是完全等同的。这里的变量是指实例字段,静态字段,构成数组对象的元素,但是不包括局部变量和方法参数(因为这是线程私有的)。

Java内存模型中涉及到的概念有:

  • 主内存:java虚拟机规定所有的变量(不是程序中的变量)都必须在主内存中产生。可以与前面说的物理机的主内存相比,只不过物理机的主内存是整个机器的内存,而虚拟机的主内存是虚拟机内存中的一部分。
  • 工作内存:java虚拟机中每个线程都有自己的工作内存,该内存是线程私有的。可以与前面说的高速缓存相比。线程的工作内存保存了线程需要的变量在主内存中的副本。虚拟机规定,线程对主内存变量的修改必须在线程的工作内存中进行,不能直接读写主内存中的变量。不同的线程之间也不能相互访问对方的工作内存。如果线程之间需要传递变量的值,必须通过主内存来作为中介进行传递。

工作内存和主内存的划分和 Java 堆,栈,方法区的划分不同,两者基本没有关系,如果勉强对应,则主内存可理 解为堆中实例数据部分,工作内存则对应栈中部分区域

关于Java 堆,栈,方法区:点击学习

【4】volatile的内存语义

volatile写的内存语义:
当写一个变量的时候,JMM会把该线程的私有内存中的共享变量值更新到主内存中,并将其他线程中的值置为无效的;
volatile读的内存语义:
当读一个变量的时候,JMM会先判断是否私有空间内的值是否失效,若失效,线程接下来会从主存中读取变量。

详情见:点击学习

【5】锁的内存语义

当线程释放锁时,JMM会把该线程对应的本地内存中的共享变量刷新到主内存中。

当线程获取锁时,JMM会把该线程对应的本地内存置为无效。从而使得被监视器保护的临界区代码必须要从主内存中去读取共享变量。

详情见:点击学习

十二、深入理解Java内存模型的更多相关文章

  1. 《深入理解Java虚拟机》笔记--第十二章、Java内存模型与线程

    主要内容:虚拟机如何实现多线程.多线程之间由于共享和竞争数据而导致的一系列问题及解决方案. Java内存模型:     Java内存模型的主要目标是定义程序中各个变量的访问规则,即在虚拟机中将变量存储 ...

  2. java内存模型(二)深入理解java内存模型的系列好文

    深入理解java内存模型(一)--基础 深入理解java内存模型(二)--重排序 深入理解java内存模型(三)--顺序一致性 深入理解java内存模型(四)--volatile 深入理解java内存 ...

  3. Java并发(二):Java内存模型

    一.硬件内存架构 一个现代计算机通常由两个或者多个CPU.其中一些CPU还有多核.每个CPU在某一时刻运行一个线程是没有问题的.如果你的Java程序是多线程的,在你的Java程序中每个CPU上一个线程 ...

  4. 【并发编程】一文带你读懂深入理解Java内存模型(面试必备)

    并发编程这一块内容,是高级资深工程师必备知识点,25K起如果不懂并发编程,那基本到顶.但是并发编程内容庞杂,如何系统学习?本专题将会系统讲解并发编程的所有知识点,包括但不限于: 线程通信机制,深入JM ...

  5. 深入理解java内存模型系列文章

    转载关于java内存模型的系列文章,写的非常好. 深入理解java内存模型(一)--基础 深入理解java内存模型(二)--重排序 深入理解java内存模型(三)--顺序一致性 深入理解java内存模 ...

  6. 深入理解Java内存模型之系列篇[转]

    原文链接:http://blog.csdn.net/ccit0519/article/details/11241403 深入理解Java内存模型(一)——基础 并发编程模型的分类 在并发编程中,我们需 ...

  7. 【深入理解Java内存模型】

    深入理解Java内存模型(一)--基础 深入理解Java内存模型(二)--重排序 深入理解Java内存模型(三)--顺序一致性 深入理解Java内存模型(四)--volatile 深入理解Java内存 ...

  8. 全面理解Java内存模型(JMM)及volatile关键字(转载)

    关联文章: 深入理解Java类型信息(Class对象)与反射机制 深入理解Java枚举类型(enum) 深入理解Java注解类型(@Annotation) 深入理解Java类加载器(ClassLoad ...

  9. 深入理解 Java 内存模型(一)- 内存模型介绍

    深入理解 Java 内存模型(一)- 内存模型介绍 深入理解 Java 内存模型(二)- happens-before 规则 深入理解 Java 内存模型(三)- volatile 语义 深入理解 J ...

随机推荐

  1. linux学习之Ubuntu

    查看自己的ubuntu版本,输入以下命令(我的都是在root用户下的,在普通用户要使用sudo)第一行的lsb是因为没有安装LSB,安装之后就不会出现这个东西.LSB(Linux Standards ...

  2. What is Java virtual machine?

    Java Virtual Machine (JVM) is a specification that provides runtime environment in which java  bytec ...

  3. [反汇编]函数开始部分利用mov ebx,esp找到返回地址(_KTRAP_FRAME结构)

    我们理解call原理,首先将返回地址压入栈中,之后执行调用. 因此,在一个函数开始部分,esp依旧是上一个栈帧的esp,此时esp指向返回地址. 这就意味着使用 mov ebx,esp,之后 [ebx ...

  4. node.js的async和await

    一.async和await是什么 ES2017 标准引入了 async 函数,使得异步操作变得更加方便,async其实本质是Generator函数的语法糖 async表示函数里有异步操作 await表 ...

  5. sql server 随记 -- 月份/日期 查询

    月份 SELECT * FROM ( ] ) a UNPIVOT ( xxx ]) ) a2; 日期 SELECT * FROM ( ] )a UNPIVOT( xxx ]) )a2 (存档)

  6. 解决真机编译出现System.DllNotFoundException: 'libmono-native.so'错误都方法

    1.去掉勾选:使用共享运行时 2 检查android SDK是否安装了NDK 3.使用真机运行编译APK

  7. DataGridView中的rows.Count比实际行数多1的原因以及解决办法

    场景 DataGridView怎样实现添加.删除.上移.下移一行: https://blog.csdn.net/BADAO_LIUMANG_QIZHI/article/details/10281414 ...

  8. SpringCloud之API网关与服务发现——Cloud核心组件实战入门及原理

    微服务发展历史 单体模式——>服务治理(服务拆分)——>微服务(细分服务)——>Segments(服务网格) 微服务 VS SOA 微服务:模块化.独立部署.异构化 SOA:共同的治 ...

  9. PHP fread 文件系统函数

    定义和用法 fread - 读取文件(可安全用于二进制文件) 版本支持 PHP4 PHP5 PHP7 支持 支持 支持 语法 fread ( resource $handle , int $lengt ...

  10. elasticsearch中文搜索优化

    遇到的问题 检索葡萄糖关键字,希望结果仅包含葡萄糖,不包含葡萄:检索葡萄,希望结果包含葡萄糖. 同义词如何配置 如何确保搜索关键词被正确分词 分析器分词流程 分析器扮演着非常重要的角色,ES提供的有内 ...