Java内存模型(Memory Model)

Java内存模型(Memory Model)

  

  Java内存模型,Java Memory Model,我个人更喜欢“Java存储模型”的译法。

  介绍

  如前所述,JVM被设计成一台抽象的虚拟计算机,JVM的并发问题及解决方案与物理计算机中的并发问题有很多相似之处。

  由于现代计算机的内存与CPU在运算速度上的巨大差别,通常会加入一层更接近CPU读写速度的高速缓存(Cache),将运算使用到的数据复制到Cache中,让运算能加速进行,运算结束后再从Cache同步回内存之中。这个设计解决了速度的矛盾,也带来了一个新的问题:缓存一致性。在多CPU系统中,每个CPU都有自己的Cache,它们共享同一主内存,当多个CPU的运算任务涉及同一块内存区域时,就可能导致各自的Cache数据不一致。对此又设计了“缓存一致性协议”,如MESI,要求各个CPU在读写Cache时,都遵循这些协议进行操作,以解决缓存数据不一致的问题。“内存模型”(Memory Model),就是在特定的协议下,对特定的高速缓存读写访问过程进行抽象。不同架构的物理机器拥有不一样的内存模式,而Java虚拟机也有自己的内存模型,其基础原理是共通的。

  此外,为了充分利用CPU的运算单元,可能会对输入代码进行乱序执行优化,只保证执行结果的一致性,但不保证各语句的计算顺序与输入代码一致。Java虚拟机的即时编译器也有类似的指令重排序优化。

  Java语言规范中试图定义一种Java内存模型,以实现Java程序在各种平台上能达到一致的内存访问效果,为多线程的同步和避免数据争用提供一套有效平衡高吞吐与一致性的保障机制。

  什么是Java内存模型

  一个内存模型描述的是,给定程序的某个特定的执行轨迹(trace)是否是该程序的一个合法执行。Java内存模型检查执行轨迹中的每次读操作,以及根据特定规则,校验该读操作观察到的写是否合法。内存模型描述了一个程序的可预期行为,具体实现时拥有充分的自由度去生成需要的代码,只要其最终执行结果可经由内存模型进行推测。

  通俗地讲,Java内存模型(JMM)定义了一系列规则,以确保某一线程的写操作能正确呈现给其他线程。JMM并没有描述多线程该如何执行,而是描述多线程允许的行为。

  JMM规定了所有的共享变量都存储在JVM的主内存中。每条线程有自己的工作内存,用于保存该线程用到的变量的主内存副本拷贝(具体实现通常不会拷贝整个对象),线程对变量的操作全部在工作内存中进行,不能直接读写主内存中的变量。不同的线程间也无法直接访问对方的工作内存,线程间变量值的传递需要通过主内存来完成。

  关于主内存和工作内存之间的具体交互协议,即一个变量如何从主内存拷贝到工作内存、如何从工作内存同步回主内存之类的实现细节,JMM定义了8种操作(lock,unlock,read,load,use,assign,store,write),虚拟机实现时必须保证以上每一种操作都是原子的、不可再分的。

  共享变量/堆内存:能够在线程间共享的内存称作“共享内存或堆内存”。所有的实例域、静态域以及数组元素都存储在堆内存中。方法中的局部变量永远不会被线程间共享,也不会受内存模型影响。我们也无需关心线程内动作,每个单线程都应遵守正确的线程内语义。

  线程间的动作:线程间的动作是由某一线程执行,能被另一线程探测或直接影响的动作。包括:

  共享变量的读/写

  同步动作 (synchronization action)

  lock/unlock某个monitor;

  读写某个volatile变量

  启动一个线程

  与外部交互的动作

  导致某个线程进入无限循环的动作(thread devergence action)

  延伸阅读

  本文参考了《深入理解Java虚拟机》、《JSR-133-MemoryModel》,有充裕时间的同学可以去完整过一遍,但原文有较多艰涩难懂之处。这里做了较大的裁剪,隐藏更深一层的信息,以求对Java内存模型能有一个快速又不过于浅显的了解。更多的概念和规则:

  缓存一致性,Cache Coherence,MESI协议

  Instruction Reorder,指令重排序

  Happens-Before关系规则

  As-If-Serial ,线程内串行的语义

  Memory Barrier,内存屏障

  参考资料:

  JSR-133 Java Memory Model

  《Java语言规范SE8》第17章 线程与锁 17.4 内存模型

  《深入理解Java虚拟机》第12章 Java内存模型与线程

转载于:https://juejin.im/post/5bebcf1ff265da610e7fa454

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/101323.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 一阶微分不变性_二阶微分形式表示

    一阶微分不变性_二阶微分形式表示首先强化一下:1.d(dx)=d2x=02.dx2=(dx)23.d(x2)=2xdx上面3者各不相同,不可混淆。dy=d(f。g(x))=f(1)(u)g(1)(x)

    2022年8月3日
    3
  • mysql 索引类型以及使用场景[通俗易懂]

    mysql 索引类型以及使用场景[通俗易懂] 关于MySQL索引的好处,如果正确合理设计并且使用索引的MySQL是一辆兰博基尼的话,那么没有设计和使用索引的MySQL就是一个人力三轮车。对于没有索引的表,单表查询可能几十万数据就是瓶颈,而通常大型网站单日就可能会产生几十万甚至几百万的数据,没有索引查询会变的非常缓慢。还是以WordPress来说,其多个数据表都会对经常被查询的字段添加索引,比如wp_comments表中针对5个字段设计了B…

    2022年6月7日
    37
  • navcat 激活码(JetBrains全家桶)

    (navcat 激活码)好多小伙伴总是说激活码老是失效,太麻烦,关注/收藏全栈君太难教程,2021永久激活的方法等着你。IntelliJ2021最新激活注册码,破解教程可免费永久激活,亲测有效,下面是详细链接哦~https://javaforall.net/100143.htmlMLZPB5EL5Q-eyJsaWNlbnNlSW…

    2022年3月20日
    59
  • excel转json操作

    excel转json操作工作中需要用到将从数据库中下载的excel每行数据转成json文件,用于规则回溯,参考网上资料,通过以下代码可实现:importpandasaspdimportnumpyasnpimportjsonimportdatetime#导入数据#由于phone2有缺失值,如果不加converters={‘phone2’:str},导致读入会变成float形式,导致有值的手机号码后会加点0,如13812341234.0data=pd.read_excel(r’C:\Users\

    2022年6月12日
    37
  • 【MySQL笔记】正确的理解MySQL的MVCC及实现原理

    【MySQL笔记】正确的理解MySQL的MVCC及实现原理MVCC多版本并发控制前提概要MVCC实现原理MVCC相关问题前提概要什么是MVCC?MVCCMVCC,全称Multi-VersionConcurrencyControl,即多版本并发控制。MVCC是一种并发控制的方法,一般在数据库管理系统中,实现对数据库的并发访问,在编程语言中实现事务内存。MVCC在MySQLInnoDB中的实现主要是为了提高数据库并发性能…

    2022年4月30日
    54
  • java轻量级web框架_什么是框架

    java轻量级web框架_什么是框架JEMSF框架前言今天我们准备向广大开发人员推荐一种新的框架,暂时取名JEMSF,如果您已经对Struts、Tapestry以及Spring和Hibernat有一些了解,那么应该可以更好的理解下面的文章,JEMSF是我在工作生涯中最大的一个创造,经历了很多考验和应用的试验,最后形成JEMSF。序一种新的事物的诞生需要经历很多的考验,我自认为JEMSF是一个很好的WEB应用框架,很久以前(2…

    2025年9月30日
    2

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号