重读《深入理解Java虚拟机》七、探究Java内存模型
1、计算机物理内存结构(物理内存结构决定了虚拟机内存结构)
由于处理器和主存储设备在运算速度上不上同一个数量级上,因此处理器和主存储器之间不得不增设一层高速缓存,将部分在主存储设备的运算放在高速缓存内,从而使得内存的相关运算速度跟上处理器的运算速度不至
于限制处理器的处理速度。实际工作中,处理器要操作的数据先从主存储内存内读取到高速缓存内,然后再在高速缓存内进行运算,最后再把运算的结果会写到主存储内存内。
2、虚拟机内存模型屏蔽不同物理机器的内存模型
不同的物理机器存在不同的架构,在内存处理方式上不一样,虚拟机内存模型就是屏蔽底层硬件、操作系统在内存操作上的的差异性,使得Java程序内存的访问方式具有跨平台的特性不限定于特定的底层内存访问方式。
也就是说Java虚拟机的内存模型是对底层硬件和操作系统对内存操作方式(读写访问)的抽象。(虚拟机的内存模型是对物理机内存模型虚拟)。
虚拟机内存模型根据物理机内存模型的抽象出的模型中,线程从共享内存(主内存)中读取所需要的数据,并加载到当前线程私有的内存区域(工作内存)进行运算并将运算的结果写入当前的私有线程当中,最后在将数
据同步至共享内存当中。也就是说明了为了执行线程和获取所需的数据,数据需要在线程私有的内存和共享的内存之间进行不断的交互操作。相关线程要读取数据,需要将共享内存(主内存)当中加数据加载到线程自己的私
有内存当中进行,相关线程执行业务操作需要保存数据就需要将线程私有的内存保存至主内存内。
3、缓存一致性问题
数据在私有内存和共享内存之间进行不断的交互操作,在并发的情况下,易造成数据的不一致性(共享内存和私有内存之间的缓存数据的不一致性),因而内存之间的交互操作要遵循相应的协议,内存间的交互要根据协
议进行操作。
4、Java虚拟机内存模型
(1)主内存和工作内存
主内存:主内存是公有,各个线程共享的内存,Java内存模型规定了所有变量都存储在主内存当中,对应于虚拟机内存区域内的Java堆中的对象实例部分,可以说是对物理主内存的抽象和表示。
工作内存:线程私有的, 保存了对主内存部分变量的副本,是对主内存的拷贝。对应于虚拟机内存区域内的虚拟机栈的部分区域,可以说是对物理高速缓存或者寄存器的抽象。
(2)内存间交互操作
一个变量如何从主内存拷贝至工作内存当中?又如何将工作内存的数据同步至主内存当中?主内存和工作内存之间是如何交互的?
Java虚拟机通过8个原子操作来实现主内存和工作内存之间的交互操作
内存间交互操作的准则:
(3)内存模型对volatile变量定义的特殊规则
volatile关键字:Java虚拟机提供的轻量级同步机制
volatile的两个特性:
a.volatile变量保证对所有线程的可见性(其他线程读取volatile变量的时候必须先从主内存加载到工作内存使用),final关键字和synchronized关键字也可以实现可见性
b.禁止指令重排序优化(插入内存屏障来保证处理器不发生乱序执行)
volatile在并发下是不安全的,保证volatile并发下安全的两条规则:
a.运算结果不依赖当前变量的值或者只有单一的线程修改变量值
b.变量不需要和其他状态变量共同参与不变约束
Java内存模型中对volatile变量定义的特殊规则:
a.线程对volatile变量的use操作和volatile变量的load、read动作相关联,必须连续一起出现(load_read_use) => volatile变量可见性的保证,保证所有线程从主内存内加载的最新的值
b.线程对volatile变量的assign操作和store、write动作相关联,必须连续一起出现 (assign_store_write) => volatile变量可见性的保证,将当强最新的值同步至主内存,保证其他线程对最新纸的可见性
c.如果线程A对volatile变量的use或assign操作先于其他线程的use或assign则,线程A对该线程的load或者store操作必定先于其他线程的load或者store操作 =>禁止指令的重排序优化
(4)long和double的非原子性协定
虚拟机允许不保证64位数据类型的load、store、 read、write 4个操作的原子性,但是商用虚拟机都选择把64位数据的读写操作作为原子操作。
(5)内存模型的3个特性
a.原子性:虚拟机模型通过内存间原子性的交互操作来保证内存的访问操作即使在并发操作仍是安全的
b.可见性:规定相关原子性操作的组合来实现变量值在所有线程间的可见性
c.有序性:通过禁止指令重排序优化,来达到代码执行的有序性
( 6)先行发生原则:判断数据是否存在竞争、线程是否安全的主要依据
对于先行发生的操作,虚拟机不进行重排序。
Java内存模型内默认不重排序的情况(天然的先天发生):
a、程序次序规则:程序代码本身的次序的先天发生,代码前面的操作先于后面代码的操作
b.管程锁定规则:同一个锁的lock操作必定先于unlock操作
c.volatile变量规则:volatile变量的写操作必定先于该变量的读操作(volatile变量的可见性保证)
d.线程启动规则:线程的启动方法start()必定先于线程的其他任何操作
e.线程终止规则:线程的终止检测必定晚于线程的任何操作
f.线程中断规则:线程的interrupt中断方法必定先去线程中断事件检测方法的
g.对象终结规则:对象的初始化操作必定先于对象的finalize()
h.传递性规则:线程先行发生的传递性
重读《深入理解Java虚拟机》七、探究Java内存模型的更多相关文章
- Java虚拟机解析篇之---内存模型
今天闲来无事来,看一下Java中的内存模型和垃圾回收机制的原理.关于这个方面的知识,网上已经有非常多现成的资料能够供我们參考,可是知识还是比較杂的,在这部分知识点中有一本书不得不推荐:<深入理解 ...
- 深入理解java虚拟机(6)---内存模型与线程 & Volatile
其实关于线程的使用,之前已经写过博客讲解过这部分的内容: http://www.cnblogs.com/deman/category/621531.html JVM里面关于多线程的部分,主要是多线程是 ...
- 深入理解Java虚拟机读书笔记8----Java内存模型与线程
八 Java内存模型与线程 1 Java内存模型 ---主要目标:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节. ---此处的变量和J ...
- 深入理解Java虚拟机(七)——类文件结构
Java的无关性 由于计算机领域中有很多操作系统和硬件平台同时在竞争,所以,很多编程语言的程序设计会与其运行的平台和操作系统产生耦合,这样就大大增加了程序员的工作,为了适应不同的平台,需要修改很多代码 ...
- 《深入理解 Java 虚拟机》学习 -- Java 内存模型
<深入理解 Java 虚拟机>学习 -- Java 内存模型 1. 区别 这里要和 JVM 内存模型区分开来: JVM 内存模型是指 JVM 内存分区 Java 内存模型(JMM)是指一种 ...
- 《深入理解 Java 虚拟机》学习笔记 -- 内存区域
<深入理解 Java 虚拟机>学习笔记 -- 内存区域 运行时数据区域 主要分为 6 部分: 程序计数器 虚拟机栈 本地方法栈 Java 堆 方法区 如图所示: 1. 程序计数器(线程私有 ...
- 深入理解Java虚拟机之图解Java内存区域与内存溢出异常
Java内存区域与内存溢出异常 运行时数据区域 程序计数器 用于记录从内存执行的下一条指令的地址,线程私有的一小块内存,也是唯一不会报出OOM异常的区域 Java虚拟机栈 Java虚拟机栈(Java ...
- 深入理解Java虚拟机(一)、Java内存区域与内存溢出异常
Java虚拟机所管理的内存包括以下几个运行时数据区: 程序计数器(PCR): 1.是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器 2.为线程私有 3.执行Java方法有PCR,执行 ...
- 【深入理解JAVA虚拟机】第二部分.内存自动管理机制.1.内存区域
1.内存区域 根据<Java虚拟机规范(Java SE 7版)> 的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如图所示. 程序计数器 当前线程所执行的字节码的行号指 ...
- 深入理解java虚拟机读书笔记1--java内存区域
Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随 ...
随机推荐
- Java编程的逻辑 (80) - 定时任务的那些坑
本系列文章经补充和完善,已修订整理成书<Java编程的逻辑>,由机械工业出版社华章分社出版,于2018年1月上市热销,读者好评如潮!各大网店和书店有售,欢迎购买,京东自营链接:http: ...
- VirtualBox 4.3“不能为虚拟电脑 打开一个新任务”解决方案 - 转
最近做项目因为设计不同网络,还要大家文件和数据库服务器环境,所以需要多台机器进行测试,最简单的方法当然是跑多个虚拟机了.虽然不可否认 VMware 确实强大,不过相比较起来我更喜欢功能比较简单轻省的 ...
- 安卓程序代写 网上程序代写[原]Android中的回调Callback
回调就是外部设置一个方法给一个对象, 这个对象可以执行外部设置的方法, 通常这个方法是定义在接口中的抽象方法, 外部设置的时候直接设置这个接口对象即可. 1. 如何定义一个回调 a. 定义接口 : 在 ...
- 【消息】Pivotal Pivots 开源大数据处理的核心组件
Pivotal Pivots 开源大数据处理的核心组件 Pivotal 今天宣布将其大数据套件的三个核心组件开源,同时商业版本继续提供更高级特性和商业支持服务. 这三个开源的组件分别是: GemFir ...
- 转:UML工具Astah的使用
原文链接:http://blog.csdn.net/vipygd/article/details/9182247 前言 UML是软件工程中非常重要的知识点.我们经常要去展示各种UML图,当然,我们要将 ...
- tensorflow随机梯度下降算法使用滑动平均模型
在采用随机梯度下降算法训练神经网络时,使用滑动平均模型可以提高最终模型在测试集数据上的表现.在Tensflow中提供了tf.train.ExponentialMovingAverage来实现滑动平均模 ...
- CentOS7 yum方式安装MariaDB 10.2.13-1
注:以下步骤都是以root身份运行. 一.建立mariadb.repo 1,编辑新文件,命令:vim /etc/yum.repos.d/mariadb.repo 2,输入如下内容,保存退出 [mar ...
- php 启动服务器监听
使用命令 php -S 域名:端口号 -t 项目路径 截图如下: 原本是通过localhost访问的 现在可以通过 127.0.0.1:8880 访问 此时命令行终端显示如下:
- cordova 企业应用打包Archive的时候报 "#import <Cordova file not found"
可能原因是Cordova的路径问题: For xcode7 add "$(OBJROOT)/UninstalledProducts/$(PLATFORM_NAME)/include" ...
- 智能文件选择列表—— bat 批处理
智能文件选择列表 *.wim @echo off setlocal enabledelayedexpansion title 智能文件选择列表 pushd %~dp0 & cd /d %~dp ...