java内存模型的历史变迁

     2022-03-17     701

关键词:

本文通过介绍Java的新/旧内存模型,来展示Java技术的历史变迁。

旧的Java内存模型

Java使用的是共享内存的并发模型,在线程之间共享变量。Java语言定义了线程模型规范,通过内存模型控制线程与变量的交互,从而实现Java线程之间的通信。在JDK5之前,Java一直使用的是旧内存模型。如图1所示。变量保存在由所有线程共享的主内存中,主内存中的变量称为mastingcopy。每个线程都有一个工作内存,它保存变量的workingcopy。旧的内存模型定义了若干规则,通过这些规则来保证线程何时将主内存中的mastingcopy传送到线程的工作内存中;以及线程何时将工作内存中的workingcopy传送回主内存。旧内存模型使用8个操作来定义线程可以执行的动作。

  • read(读)操作:主内存把mastingcopy传送到线程的工作内存,以供后面的load操作使用。
  • load(装载)操作:线程将由read操作从主内存传送过来的值,放入工作内存中。
  • use(使用)操作:线程将变量的workingcopy传送到线程执行引擎。
  • assign(赋值)操作:线程将变量值从线程执行引擎传送到线程的工作内存中。
  • store(存储)操作:线程将变量的workingcopy传送到主内存,供后面的write操作使用。
  • write(写)操作:主内存将由store操作传送过来的值,放入主内存中。
  • lock(锁定)操作:线程获得指定对象的锁。
  • unlock(解锁)操作:线程释放指定对象的锁。

技术分享

图1 Java旧内存模型

这里的关键是,由于read操作是由主内存执行,而对应的load是由线程执行,read操作和load操作之间是松散耦合的。也就是说,主内存和线程工作内存之间的变量传递是松散耦合的。同样,由于store操作是由线程执行,而对应的write是由主内存执行,store操作和write操作之间是松散耦合的。也就是说,线程工作内存和主内存之间的变量传递是松散耦合的。旧Java内存模型对Java实现如何执行变量的读/写,加锁/解锁,以及Volatile变量的读/写,定义了非常严格的规则。这些规则非常复杂,具体详情请参考《JVM规范》,这里就不赘述了。旧Java内存模型通过这些复杂的规则,来保证多线程程序的线程之间,可以可靠地传递共享变量,从而保证多线程程序的正确性。

新的Java内存模型

从JDK5开始,Java使用新的内存模型,新内存模型完全抛弃了旧内存模型的主内存和工作内存的概念,也抛弃了旧内存模型的8个内存操作。也就是说,新内存模型完全是重新设计的。

新内存模型引入了一个新的概念,叫happens-before。happens-before的概念最初由LeslieLamport在其一篇影响深远的论文(《Time,ClocksandtheOrderingofEventsinaDistributedSystem》)中提出。LeslieLamport使用happens-before来定义分布式系统中,事件之间的一个偏序关系(partialordering)。LeslieLamport在这篇论文中给出了一个分布式算法,该算法可以将该偏序关系扩展为某种全序关系。

JSR-133使用happens-before的概念来指定两个操作(这里的操作是指程序中对变量的读/写,对锁的加锁和解锁)之间的执行顺序。新内存模型定义了如下的happens-before规则。

  • 程序顺序规则:一个线程中的每个操作,happensbefore于该线程中的任意后续操作。
  • 监视器锁规则:对一个锁的解锁,happens-before于随后对这个锁的加锁。
  • volatile变量规则:对一个volatile域的写,happensbefore于任意后续对这个volatile域的读。
  • 传递性:如果Ahappens-beforeB,且BhappensbeforeC,那么Ahappens-beforeC。
  • start()规则:如果线程A执行操作ThreadB.start()(启动线程B),那么A线程的ThreadB.start()操作happensbefore于线程B中的任意操作。
  • join()规则:如果线程A执行操作ThreadB.join()并成功返回,那么线程B中的任意操作happens-before于线程A从ThreadB.join()操作成功返回。

由于两个操作可以在一个线程之内,也可以是在不同线程之间。因此JMM可以通过happens-before关系向程序员提供跨线程的内存可见性保证(如果A线程的写操作a与B线程的读操作b之间存在happens-before关系,尽管a操作和b操作在不同的线程中执行,但JMM

技术分享

图2新内存模型的设计示意图

向程序员保证a操作将对b操作可见)。在新内存模型向程序员提供happens-before规则,程序员只需要与happens-before打交道即可,因此Java程序员的学习负担大大降低。同时,新内存模型允许不会改变程序结果的重排序,这可以最大限度地放松对编译器和处理器的束缚,新内存模型的执行性能比旧内存模型要好。

深入java内存模型

在介绍Java内存模型之前,我们先来看一下到底什么是计算机内存模型,然后再来看Java内存模型在计算机内存模型的基础上都做了哪些事情。要说计算机的内存模型,就要说一段古老的历史,看一下为什么要有内... 查看详情

android源码变迁

...问题参考文献前言突发奇想的想了解下Android各个版本的历史变迁,当然不是说功能的变迁,仅仅是源代码的一些变化,所以突然想利用Git工具对各版本的历史变化做了个整理。GitHub目前在GitHub上整理了SDK工具中能够... 查看详情

java内存模型

Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的。Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为Java内存模型。如果你想设计表现良好的并发程序,理解Java内存... 查看详情

并发艺术--java内存模型

前言  本章大致分为四部分。java内存模型的基础,介绍内存模型的相关基本概念;java内存模型中的顺序一致性,主要介绍重排序和顺序一致性;同步原语,涉及synchronized,volatile,final三个同步原语的内存含义及重排序等;jav... 查看详情

android源码变迁

...问题参考文献前言突发奇想的想了解下Android各个版本的历史变迁,当然不是说功能的变迁,仅仅是源代码的一些变化,所以突然想利用Git工 查看详情

java内存模型

Java内存模型Java虚拟机规范中试图定义一种Java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。Java内存模型的主要目标是定义程序中各个变量的访问规则,即... 查看详情

认识java

...的?除了虚拟机,还有哪些跨平台方式其他主流语言的内存管理是怎么做的?Java里都有哪些语法糖什么是Java模块化Java的程序计数器和cpu的计数器有啥区别?栈帧是啥程序运行的某个时刻,Java中没有被调用代码,是... 查看详情

java内存模型

Java虚拟机规范试图定义一种Java内存模型来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的并发效果。在JDK1.5发布后,Java的内存模型已经成熟和完善起来了。1.主内存与工作内存:Java... 查看详情

第三章java内存模型(上)

 本章大致分为4部分:Java内存模型的基础:主要介绍内存模型相关的基本概念Java内存模型中的顺序一致性:主要介绍重排序和顺序一致性内存模型同步原语:主要介绍3个同步原语(synchroized、volatile和final)的内存语义及重... 查看详情

java内存模型(代码片段)

1、简介    Java内存模型规范了Java虚拟机与计算机内存是如何协同工作的。Java虚拟机是一个完整的计算机的一个模型,因此这个模型自然也包含一个内存模型——又称为Java内存模型。    如果你想设计表现良好的并发程... 查看详情

java内存模型

为何需要java内存模型(JavaMemoryModel,JMM):  用于屏蔽各种操作系统和硬件之间的内存访问差异,使得java能够在各种平台下能够达到一致的运行结果。java内存模型(虚拟机内存):  1、主内存:所有的变量都存储在主内存... 查看详情

02java内存模型

java内存模型1、JVM内存区域方法区:类信息、常量、static、JIT(信息共享)java堆:实例对象GC(信息共享)OOMVMstack:JAVA方法在运行的内存模型(OOM)PC:java线程的私有数据,这个数据就是执行下一条指令的地址Nativemethodstack:月JVM的native... 查看详情

java内存模型

声明:转载自茶轴的青春的博客??网上有很多关于Java内存模型的文章,在《深入理解Java虚拟机》和《Java并发编程的艺术》等书中也都有关于这个知识点的介绍。但是,很多人读完之后还是搞不清楚,甚至有的人说自己更懵了。... 查看详情

java内存模型

1.java内存模型是什么?java内存模型即JavaMemoryModel,简称JMM,其规范了Java虚拟机与计算机内存时如何协同工作的,规定了一个线程如何和何时看到其他线程修改过的值,以及在必须时,如何同步访问共享变量。    2... 查看详情

java内存模型

JVM(三)Java内存模型指的是JMM(JavaMemoryModel)、是Java虚拟机规范中定义的一种模型、试图屏蔽硬件和操作系统的内存的访问差异的,为了让Java程序在各种的平台达到一致的内存访问效果。Java内存模型的主要... 查看详情

java并发编程--java内存模型

Java内存模型前面讲到了Java线程之间的通信采用的是共享内存模型,这里提到的共享内存模型指的就是Java内存模型(简称JMM),JMM决定一个线程对共享变量的写入何时对另一个线程可见。从抽象的角度来看,JMM定义了线程和主内存... 查看详情

java内存模型

Java内存模型(JavaMemoryModel,JMM),Java虚拟机规范中定义的来屏蔽掉各种硬件和操作系统的内存访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问结果。1、主内存与工作内存Java内存模型的主要目标是定义程序中... 查看详情

java内存模型-jmm

定义Java内存模型(JavaMemoryModel),定义了JVM在计算机内存上的工作方式。JVM是对整个计算机的虚拟模型,所以JMM是隶属于JVM的。如果我们要想深入了解Java并发编程,就要先理解好Java内存模型。Java内存模型定义了多线程之间共... 查看详情