JVM内存结构与内存模型

1、 Jvm内存结构

模块分解数组

1. 程序计数器(线程私有)

(1) 是什么?

    程序计数器是当前线程所执行的字节码的行号指示器。缓存

(2) 做用?

    字节码解释器经过改变这个计算器的值来选择下一条须要执行的字节码指令,分支,循环,跳转,异常处理,线程恢复,若是执行的是Native方法,这个计算器的值则为空并发

2. Java虚拟机栈(线程私有)

(1) 是什么

    Java虚拟机栈描述的是Java方法执行的内存模型:每一个方法在执行的同时都会建立一个栈帧,每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机栈中入栈到出栈的过程。post

(2) 组成

① 局部变量表

    存放了编译期可知的基本类型、对象引用类型和returnAddress类型(指向一条字节码指令的地址。即程序就是存储在方法区的字节码指令,而 returnAddress 类型的值就是指向特定指令内存地址的指针)this

② 操做数栈

    操做数是一个后入先出栈,JVM全部的操做码都是对操做数栈上的数据进行操做,对于每个方法的调用,JVM会创建一个操做数栈,以供计算使用。操作系统

    例如 a = b + c 的字节码执行过程当中操做数栈以及局部变量表的变化以下图所示。线程

    局部变量表中存储着a、b、c 三个局部变量,首先将b和c分别入栈

③ 动态连接

    运行期间转化为直接引用,就称为动态连接。Class字节码的常量持中存有大量的符号引用,在运行期才将符号引用变成直接引用(也就是指向数据),能够是方法或者字段的引用。3d

④ 方法出口

    即本方法执行后下一步指令的地址,方法正常退出时,调用者PC计数器的值就能够做为返回地址,异常退出时,返回地址是要经过异常处理器来肯定。指针

3. 本地方法栈(线程私有)

(1) 是什么?

    保存native方法进入区域的地址cdn

4. Java堆(线程共享)

(1) 是什么?

    全部的对象实例以及数组都要在堆上分配。是垃圾收集器管理的主要区域。

(2) 分区

① 新生代: Eden区、Survivor From区、Survivor To区
② 老年代

5. 方法区(线程共享)

(1) 是什么

    方法区用于存储已被虚拟机加载的类信息、方法、常量、静态成员变量、JIT(即时编译器)编译后的代码等数据,在类加载时分配。

(2) 也叫非堆,分配在元空间

    元空间:类的元数据,如方法数据、方法信息(字节码,栈和变量大小)、运行时常量池、已肯定的符号引用和虚方法表等方法区的数据,保存在本地内存区域(堆外内存)

6. 运行时常量池(线程共享)

(1) 是什么

    运行时常量池用于存放编译期和运行期生成的各类字面量和符号引用。这部份内容将在类加载后进入方法区的运行时常量池中存放。属于方法区的一部分

(2) 字面量和符号引用

    字面量:1.字符串;2.基本类型值;3.final常量     符号引用:1.类和方法的全限定名;2.字段的名称和描述符;3.方法的名称

2、 Jvm内存模型

1. 定义

    因为不一样平台内存模型的差别,有可能致使程序在不一样平台的并发访问出错。Java内存模型(Java Memory Model,JMM)是屏蔽各类硬件和操做系统的内存访问差别,以实现让Java程序在各类平台下都能达到一致的内存访问效果。

2. 具体操做

    定义程序中各个变量的访问规则,即在虚拟机中将变量存储到内存和从内存中取出变量的底层细节。
    此处的变量是指实例字段,静态字段和构成数组对象的元素,不包括局部变量与方法参数

3. 主内存和工做内存

    Jvm内存模型规定全部的变量都存储在主内存中,每条线程还有本身的工做内存,工做内存保存了被该线程使用到的变量的主内存副本拷贝。

4. synchronization、final、volatile

(1) synchronization

① 互斥

    对于一个monitor对象,当被一个线程持有,其余线程只能等待

② 可见性

    保证了线程在同步代码块期间写入动做,对于后续进入该代码块的线程是可见的(持有相同monitor对象的线程)。
    当前线程释放monitor对象,做用是把cpu缓存数据刷新到主内存中;其余线程进入该代码块时,须要获取monitor对象,会使cpu缓存失效,从而使变量从主内存中从新加载。

③ 禁止指令重排序

(2) final

① 禁止指令重排序
② 可见性

    被final修饰的字段在构造器中一旦初始化完成,而且构造器没有把”this”引用传递出去(“this”引用逃逸是一件很危险的事情,其余线程有可能经过这个引用访问到”初始化了一半”的对象),那么其余线程就能看见final字段的值。

(3) volatile

① 可见性
② 禁止指令重排序

5. 示例

(1) 重排序

(2) 可见性

(3) 互斥性

做者:陶章好
连接:juejin.im/post/5d6281… 来源:掘金 著做权归做者全部。商业转载请联系做者得到受权,非商业转载请注明出处。

相关文章
相关标签/搜索