Java内存模型之模型概述

一、学习前的准备

笔者认为学习任何知识之前脑海中都要有几个问题或者目标:
A、它叫什么?
B、它从哪里来?
C、要学习好它需要做哪些准备?
D、它的目的是什么或者说它能解决什么问题?

二、目标问题的答疑

1. 它叫什么

Java内存模型(Java Memory Model,JMM)

2. 它从哪里来

在《Java虚拟机规范》的第二版及之前,专门有一章“Thread and Locks”来描述内存模型,后来由于部分内容难以把握宽紧限度,被反复修正更新,从第三版(Java SE 7版)开始,索性就被移除了规范,独立以《Java 规范提案》(Java Specification Requests,JSR)形式维护。

JSR-133规范,即《JavaTM内存模型与线程规范》,由JSR-133专家组开发。

JSR是指向JCP(Java Community Process)提出新增一个标准化技术规范的正式请求。任何人都可以提交JSR,以向Java平台增添新的API和服务。JSR已成为Java界的一个重要标准。

3. 要学习好它需要做哪些准备

1)	为什么会有线程不安全的问题的存在?

2)	Java虚拟机(JVM)中运行时数据区分为哪些?哪些为线程私有的?哪些是线程共享的?

3)	在Java多线程环境中,什么是可见性?(此问题下节会讲解,本节不理解也无关系)

4)	什么是原子操作?(此问题下节会讲解,本节不理解也无关系)

4. 它的目的是什么

Java内存模型的主要目的是定义程序中各种变量的访问规则,即关注在虚拟机中把变量值存储到内存和从内存中取出变量值的这样的底层细节。

第二个目的就是来屏蔽各种硬件和操作系统的内部访问差异,以实现让Java程序在各种平台下都能达到一致的内存访问效果。

以上两段话摘抄自周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》。

其实要是按我的(片面)理解,JMM的目的就是:定义一种在多线程并发时对共享内存的操作规则。

三、好戏开场

1. 物理计算机的并发

众所周知,我们的物理计算机的内存大致分为三层:三级(L1、L2、L3)高速缓存、内存、磁盘。

出现这种情况的根本原因(矛盾)就是:现如今的CPU超级快的计算速度和普通的存储设备超级慢的读写速度造成的。于是乎现代计算机系统不得不加入一层或多层读写速度尽可能接近处理器运算速度的高速缓存(Cache)来作为内存与处理器之间的缓冲:将运算需要的数据复制到缓存中,让运算能快速进行,当运算结束后再从缓存同步回内存之中,这样处理器就无需等待缓慢的内存读写了。

基于此于是又产生了一个的问题:缓存一致性。因为在多核计算机中每个CPU都有自己的高速缓存,而他们又共享同一主内存,这种系统称为共享内存多核系统,入下图所示。

处理器、高速缓存、主内存间的交互关系

这样的系统存在一个问题:当多个处理器的任务涉及到同一块主内存区域时,而此时各个处理器的高速缓存中的数据又不一致,那此时将谁的缓存数据同步回主内存中呢?而此时就需要有一种规范一种协议去解决这种问题的发生。	

而Java的内存模型就是参考了物理计算机的这种内存布局。

2. Java的内存模型

1) 肢解Java内存模型

笔者大致喜欢将一个概念或者知识点拆分出来研究,JMM大致有以下一些知识点:主内存、工作内存、线程、副本拷贝。话不多说,先上图:

线程、主内存、工作内存间的交互关系

读者可能会发现这张图和物理计算机的内存布局几乎一模一样。我们可以和上图做一个类比以便于理解。

主内存,JMM规定了所有的变量都存储在主内存中(此处的主内存与介绍物理硬件时提到的主内存名字一样,两者可以类比,但物理上它仅是虚拟机内存的一部分)。

工作内存,每条线程还有自己的工作内存(可与前面讲的处理器高速缓存类比),线程的工作内存保存了被该线程使用的变量的主内存副本拷贝。

副本拷贝,是指线程工作内存中要使用到的变量必须从主内存中拷贝一个副本,因为线程对所有变量的操作(读取、赋值等)都必须在工作内存中进行,而不能直接读写主内存中的数据。

2) JMM与JVM运行时数据区的区别

笔者在网络上查询了很多关于此问题的答案,结果不尽如人意,各种水文和左顾而言他。

其实JMM跟JVM运行时数据区没什么太大的关系,他们是两个层面的问题。我的理解是:JMM是一种解决多线程并发对主内存访问产生竞争问题的解决方案。而JVM虚拟机运行时数据区,就是在JVM运行时对系统内各类数据进行了一次区域和类型的划分,此举更多的目的在于便于数据管理和内存回收。

但是一分析他们两者,又感觉有很多的相似之处(笔者在这个地方也是迷了很久,总是忍不住拿来做对比)。从变量、工作内存、主内存的定义来看,主内存主要对应于Java堆中的对象实例数据部分,而工作内存则对应于虚拟机栈中的部分区域。从更深层次上来说,主内存直接对于物理硬件的内存,而为了获取更好的运行速度,虚拟机可能会让工作内存优先存储于寄存器和高速缓存中,因为程序运行时主要访问的就是工作内存。

四、阶段性总结

以上就是笔者对Java内存模型最基本的一个解释和阐述。其中很多的文字都摘抄自周志明老师的《深入理解Java虚拟机:JVM高级特性与最佳实践》,这本书我真的很喜欢。

因为篇幅的原因关于“缓存一致性协议”这部分内容放到下一节在详细阐述,因为这部分的内容还是比较枯燥和繁琐的。

另外,上述提到的几个准备问题也希望大家尽快理解了,还是比较重要的知识点。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值