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内存模型的更多相关文章

  1. Java虚拟机解析篇之---内存模型

    今天闲来无事来,看一下Java中的内存模型和垃圾回收机制的原理.关于这个方面的知识,网上已经有非常多现成的资料能够供我们參考,可是知识还是比較杂的,在这部分知识点中有一本书不得不推荐:<深入理解 ...

  2. 深入理解java虚拟机(6)---内存模型与线程 & Volatile

    其实关于线程的使用,之前已经写过博客讲解过这部分的内容: http://www.cnblogs.com/deman/category/621531.html JVM里面关于多线程的部分,主要是多线程是 ...

  3. 深入理解Java虚拟机读书笔记8----Java内存模型与线程

    八 Java内存模型与线程   1 Java内存模型     ---主要目标:定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量这样的底层细节.     ---此处的变量和J ...

  4. 深入理解Java虚拟机(七)——类文件结构

    Java的无关性 由于计算机领域中有很多操作系统和硬件平台同时在竞争,所以,很多编程语言的程序设计会与其运行的平台和操作系统产生耦合,这样就大大增加了程序员的工作,为了适应不同的平台,需要修改很多代码 ...

  5. 《深入理解 Java 虚拟机》学习 -- Java 内存模型

    <深入理解 Java 虚拟机>学习 -- Java 内存模型 1. 区别 这里要和 JVM 内存模型区分开来: JVM 内存模型是指 JVM 内存分区 Java 内存模型(JMM)是指一种 ...

  6. 《深入理解 Java 虚拟机》学习笔记 -- 内存区域

    <深入理解 Java 虚拟机>学习笔记 -- 内存区域 运行时数据区域 主要分为 6 部分: 程序计数器 虚拟机栈 本地方法栈 Java 堆 方法区 如图所示: 1. 程序计数器(线程私有 ...

  7. 深入理解Java虚拟机之图解Java内存区域与内存溢出异常

    Java内存区域与内存溢出异常 运行时数据区域 程序计数器 用于记录从内存执行的下一条指令的地址,线程私有的一小块内存,也是唯一不会报出OOM异常的区域 Java虚拟机栈 Java虚拟机栈(Java ...

  8. 深入理解Java虚拟机(一)、Java内存区域与内存溢出异常

    Java虚拟机所管理的内存包括以下几个运行时数据区: 程序计数器(PCR): 1.是一块较小的内存空间,可以看做是当前线程所执行的字节码的行号指示器 2.为线程私有 3.执行Java方法有PCR,执行 ...

  9. 【深入理解JAVA虚拟机】第二部分.内存自动管理机制.1.内存区域

    1.内存区域 根据<Java虚拟机规范(Java SE 7版)> 的规定,Java虚拟机所管理的内存将会包括以下几个运行时数据区域,如图所示.  程序计数器 当前线程所执行的字节码的行号指 ...

  10. 深入理解java虚拟机读书笔记1--java内存区域

    Java在执行Java程序的过程中会把它所管理的内存划分为若干个不同的数据区域.这些区域都有各自的用途.创建和销毁的时间,有一些是随虚拟机的启动而创建,随虚拟机的退出而销毁,有些则是与线程一一对应,随 ...

随机推荐

  1. Leaflet API翻译

    转自: http://jsrookie.iteye.com/blog/2318972(上) http://jsrookie.iteye.com/blog/2318973(下) L.Map API各种类 ...

  2. mariadb 10.1.26 二进制包安装笔记

    报错链接:http://php.upupw.net/ank2discuss/40/6841-e.html mariadb 10.1.26 二进制版本 全名称: mariadb-10.1.26-linu ...

  3. centos7 修改root密码方式

    1 - 在启动grub菜单,选择编辑选项启动 2 - 按键盘e键,来进入编辑界面 3 - 找到Linux 16的那一行,将ro改为rw init=/sysroot/bin/sh 4 - 现在按下 Co ...

  4. Yii2中的composer

    1.下載composer 2.composer 插件或組件 3.有三處修改 a.composer require 的插件在vender下 b.同時vender下的composer文件修改 c.comp ...

  5. Android实现电话录音功能

    需求分析 电话录音是在通话的时候进行录音,所以需要使用一个服务来完成功能. 需要监听电话的状态,分为三种状态:  空闲状态 TelephonyManager.CALL_STATE_IDLE 响铃状态 ...

  6. Android四大组件之——Activity(一)定义、状态和后退栈(图文详解)

    什么是Activity 关键字:应用组件.四大组件.用户界面,交互. An Activity is an application component that provides a screen wi ...

  7. 6 CLR实例构造器

    引用类型构造器 如果我们没有定义实例构造器,那么编译器会为我们默认产生一个无参构造器. 实例对象初始化过程 为实例分配内存: 初始化附加成员,包括方法表指针和SyncBlockIndex变量(我们已经 ...

  8. 60款很酷的 jQuery 幻灯片演示和下载【转】

    jQuery 是一个非常优秀的 JavaScript 框架,使用简单灵活,同时还有许多成熟的插件可供选择,它可以帮助你在项目中加入漂亮的效果,其中之一就是幻灯片效果的实现,这是一种在有限的网页空间内展 ...

  9. Project Move from Qt 4 to Qt 5 项目工程的迁移

    将Qt4的项目迁到Qt5中并不需要新建一个Qt5的工程,可以直接在原工程文件上修改,这里我们使用的是VS2010和Qt5.4的环境,我们需要做以下修改: 1. 在工程里找到这个文件:工程名.vcxpr ...

  10. Windows NTFS 符号链接 与 Linux 软连接

    Windows NTFS 符号链接又称“符号链接”==================================== F:\>mklink /d Link_d Target 为 Link ...