参考《Inside JVM》

what is JMM?

从单词字面意思(java Memory Model)java内存模型。JMM阐述了程序中各变量的关系,比如实例变量,静态变量,数组。学过计算机底层原理的,应该还知道寄存器到内存,内存到寄存器的关系,说的白一点就是 :JMM是计算机操作系统中将变量存储到内存中,再从内存中取出变量的底层细节。

JMM变量存储结构

在java中所有的变量都是存储在主内存(Main Memory或Java Heap Memory)中的,所以这些变量对线程可以共享的,每个线程也都会有自己的工作内存(Working Memory)。当需要使用主内存中的一些变量时,线程中的工作内存就会对这些主内存中的变量进行copy然后并保存到自己的工作内存。(原因:线程中对主内存中变量的操作并不是发生在主内存,而是在每个线程自己的工作内存中进行,所以当线程之间互相访问工作内存中的变量时,是要通过java主内存为桥梁进行互相访问的)

上图可见 ,个线程将自己工作内存中变量刷新到主内存中,再由其它线程更新获取主内存中的共享变量。

JMM三大特性

原子性

执行一个程序时,从头到尾没有中断,执行完毕,或者出现异常时,程序回滚到程序最处始状态。数据的读取和存储单元的写入操作,包括实例变量,数组,静态变量都是属于原子级别的。

可见性

一个共享变量,由一个线程通过一系列操作来改变这个共享变量的值时,其它线程来读取的这个共享变量值也会随之改变。

有序性

对于平常的线程程序而言,我们都认为程序都是从前向后,依次执行的。在单线程中确实是这样,然而在多线程中,所有的执行都是没有顺序的

java 堆栈

讲堆栈之前,我们先说下java的内存管理。java中自带内存管理,也就是我们常说的GC(垃圾回收)。当JVM发现一些不再引用的对象时,就会释放这些内存,让其它需要内存的对象使用。垃圾回收器避免了悬挂引用的问题,GC同样解决来内存泄漏的问题。
Inside JVM书中的概念(比本人概括太好了,直接引用下)[编译原理]学过编译原理的人都明白,程序运行时有三种内存分配策略:静态的、栈式的、堆式的

静态存储

  静态存储——是指在编译时就能够确定每个数据目标在运行时的存储空间需求,因而在编译时就可以给它们分配固定的内存空间。这种分配策略要求程序代码中不允许有可变数据结构的存在,也不允许有嵌套或者递归的结构出现,因为它们都会导致编译程序无法计算准确的存储空间。

栈式存储

  栈式存储——该分配可成为动态存储分配,是由一个类似于堆栈的运行栈来实现的,和静态存储的分配方式相反,在栈式存储方案中,程序对数据区的需求在编译时是完全未知的,只有到了运行的时候才能知道,但是规定在运行中进入一个程序模块的时候,必须知道该程序模块所需要的数据区的大小才能分配其内存。和我们在数据结构中所熟知的栈一样,栈式存储分配按照先进后出的原则进行分配。

堆式存储

  堆式存储——堆式存储分配则专门负责在编译时或运行时模块入口处都无法确定存储要求的数据结构的内存分配,比如可变长度串和对象实例,堆由大片的可利用块或空闲块组成,堆中的内存可以按照任意顺序分配和释放。

JVM是啥

在Java虚拟机规范中,虚拟机实例的行为描述子系统而言,内存区域,数据类型和指令。这些组件描述抽象的内部架构的抽象的Java虚拟机。这些组件的目的与其说是决定内部架构的实现。更提供了一种严格定义的外部行为的实现。规范定义了所需的行为的任何Java虚拟机实现这些抽象组件及其之间的交互。每个Java虚拟机有一个类装入器子系统:加载机制类型(类和接口)指定完全限定的名称。每个Java虚拟机还提供一个执行引擎:一种机制负责执行的指令包含在加载的类的方法。

当一个Java虚拟机运行一个程序,它需要内存来存储很多东西,包括字节码和其他信息摘录加载类文件,程序实例化对象,参数方法,返回值,局部变量,计算的中间结果。Java虚拟机把这些数据都需要执行一个程序分成几个运行时数据区。虽然相同的运行时数据区以某种形式存在于每一个Java虚拟机实现,规范是相当抽象的。不同的虚拟机的实现可以有非常不同的内存限制。有些实现可能有很多内存,其它占用的内存却很少。有些实现可以利用虚拟内存,抽象性质的规范运行时数据区帮助更容易实现Java虚拟机在各种各样的电脑和设备中运行。
一些运行中的数据被当前的共享线程和其他各个线程所特有的。Java虚拟机的每个实例都有一个区域和一堆的方法。这些区域内运行的所有线程共享虚拟机。当虚拟机加载一个类文件,它解析信息类型的二进制数据中包含的类文件。这地方类型信息的方法。当程序运行时,虚拟机程序所有对象实例化到堆的地方。
Java堆栈由堆栈帧(帧)。一个堆栈帧包含一个Java方法调用的状态。当一个线程调用一个方法时,Java虚拟机把一个新的frame给Java堆栈的线程。方法完成时,虚拟机就会释放frame中的方法。Java虚拟机没有寄存器来保存中间数据值。指令集使用Java堆栈存储中间数据值。

ps: 看着英文书籍,后半部分的理解比较吃力,得苦练英文了。后续会接着上面的继续深入理解JMM,JVM的内部原理。

初识JMM的更多相关文章

  1. JVM初识、调优

    JVM是按照运行时数据的存储结构来划分内存结构的,JVM在运行java时,将他们划分成几种不同格式的数据,分别存储在不同的区域,这些数据统一称为运行时数据,运行时数据包括java程序本身的数据信息和J ...

  2. Android动画效果之初识Property Animation(属性动画)

    前言: 前面两篇介绍了Android的Tween Animation(补间动画) Android动画效果之Tween Animation(补间动画).Frame Animation(逐帧动画)Andr ...

  3. 初识Hadoop

    第一部分:              初识Hadoop 一.             谁说大象不能跳舞 业务数据越来越多,用关系型数据库来存储和处理数据越来越感觉吃力,一个查询或者一个导出,要执行很长 ...

  4. python学习笔记(基础四:模块初识、pyc和PyCodeObject是什么)

    一.模块初识(一) 模块,也叫库.库有标准库第三方库. 注意事项:文件名不能和导入的模块名相同 1. sys模块 import sys print(sys.path) #打印环境变量 print(sy ...

  5. 浅析java内存模型--JMM(Java Memory Model)

    在并发编程中,多个线程之间采取什么机制进行通信(信息交换),什么机制进行数据的同步? 在Java语言中,采用的是共享内存模型来实现多线程之间的信息交换和数据同步的. 线程之间通过共享程序公共的状态,通 ...

  6. 初识IOS,Label控件的应用。

    初识IOS,Label控件的应用. // // ViewController.m // Gua.test // // Created by 郭美男 on 16/5/31. // Copyright © ...

  7. UI篇(初识君面)

    我们的APP要想吸引用户,就要把UI(脸蛋)搞漂亮一点.毕竟好的外貌是增进人际关系的第一步,我们程序员看到一个APP时,第一眼就是看这个软件的功能,不去关心界面是否漂亮,看到好的程序会说"我 ...

  8. Python导出Excel为Lua/Json/Xml实例教程(一):初识Python

    Python导出Excel为Lua/Json/Xml实例教程(一):初识Python 相关链接: Python导出Excel为Lua/Json/Xml实例教程(一):初识Python Python导出 ...

  9. JMM(java内存模型)

    What is a memory model, anyway? In multiprocessorsystems, processors generally have one or more laye ...

随机推荐

  1. 为什么要使用GetSafeHwnd()函数

    当我们想得到一个窗口对象(CWnd的派生对象)指针的句柄(HWND)时,最安全的方法是使用GetSafeHwnd()函数,通过下面的例子来看其理由: CWnd *pwnd = FindWindow(“ ...

  2. 修改jupyter notebook的默认路径

    我的系统环境是win10,安装了anaconda3 for python 3.6.6首先需要配置notebook的变量环境:打开 cmd 输入命令 jupyter notebook --generat ...

  3. 获取url中?后面传递的参数

    function getUrlArgs(){ var url=location.href; var i=url.indexOf('?'); if(i==-1)return; var querystr= ...

  4. SQL Server 数据库空间使用情况

    GO /****** Object: StoredProcedure [dbo].[SpaceUsed] Script Date: 2017-12-01 11:15:11 ******/ SET AN ...

  5. Oracle 自定义实用函数

    一.ctod 字符转为date, create or replace function ctod(str in varchar2) return date as begin return to_dat ...

  6. JQuery中ajaxSubmit,在ie或360兼容,提交后台不能获得参数

    问题描述:360兼容模式.IE浏览器,通过ajaxSubmit提交,后台不能获得参数值 解决办法:把options.semantic这个参数改成true 代码: var ajax_option={ s ...

  7. Redis简单介绍与数据类型

    介绍 分布式缓存 NoSql:解决高并发.高可用.高可扩展,大数据存储等一系列问题而产生的数据库解决方案. Redis:键值(Key-Value)存储数据库 Redis是使用c语言开发的一个高性能键值 ...

  8. 全方面了解和学习PHP框架

    PHP框架是什么?    PHP框架提供了一个用以构建web应用的基本框架,从而简化了用PHP编写web应用程序的流程.这样不但节省开发时间,有助于建立更稳定的应用,而且减少了重复编码的开发.框架还可 ...

  9. Python-逻辑运算

    1 or 3>2 and 4<5 or 6 and 2<7

  10. 关于Xshell无法连接本地虚拟机的问题

    近期想搭建一个测试用的集群,但是!  刚开始搭第一台虚拟机就出现问题了,Xshell无法连接到虚拟机! 然后我更改了/etc/sysconfig/network-scripts/ifcfg-ens33 ...