JoJo的个人博客

记录精彩的程序人生

目录
JVM内存模型
/  

JVM内存模型

JVM 和 JMM 的区别

JVM内存模型则是指JVM的内存分区,Java代码是要运行在虚拟机上的,而虚拟机在执行Java程序的过程中会把所管理的内存划分为若干个不同的数据区域,这些区域都有各自的用途。

Java堆和方法区的区域是多个线程共享的数据区域。也就是说,多个线程可以操作保存在堆或者方法区中的同一个数据。这也就是我们常说的“Java的线程间通过共享内存进行通信”。

Java内存模型(Java Memory Model)JMM主要是为了规定了线程和内存之间的一些关系。根据JMM的设计,系统存在一个主内存(Main Memory)Java中所有变量都储存在主存中,对于所有线程都是共享的。每条线程都有自己的工作内存(Working Memory),工作内存中保存的是主存中某些变量的拷贝,线程对所有变量的操作都是在工作内存中进行,线程之间无法相互直接访问,变量传递均需要通过主存完成。Java 内存模型

JVM 内存模型

根据java虚拟机规范,java虚拟机管理的内存将分为下面五大区域。

1. 程序计数器

程序计数器是一块很小的内存空间,它是线程私有的,可以认作为当前线程的行号指示器。用于保存当前正常执行的程序的内存地址。

我们知道对于一个处理器(如果是多核cpu那就是一核),在一个确定的时刻都只会执行一条线程中的指令,一条线程中有多个指令,为了线程切换可以恢复到正确执行位置,每个线程都需有独立的一个程序计数器,不同线程之间的程序计数器互不影响,独立存储。

2. Java 栈(虚拟机栈)

与程序计数器一样,Java虚拟机栈也是线程私有的,它的生命周期与线程相同。栈描述的是 Java 方法执行的内存模型

在这个Java栈中又会含有多个栈帧,这些栈帧是与每个方法关联起来的,每运行一个方法就创建一个栈帧,每个栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。每一个方法从调用直至执行完成的过程,就对应着一个栈帧在虚拟机中入栈到出栈的过程。

当线程请求的栈深度大于虚拟机允许的栈深度,将抛出StackOverflowError

虚拟机栈空间可以动态扩展,当动态扩展是无法申请到足够的空间时,抛出OutOfMemory异常。

局部变量表

一片连续的内存空间,用来存放方法参数,以及方法内定义的局部变量,基本数据类型和对象引用类型,returnAddress类型

操作数栈

当一个方法刚刚开始执行时,其操作数栈是空的,随着方法执行和字节码指令的执行,会从局部变量表或对象实例的字段中复制常量或变量写入到操作数栈,再随着计算的进行将栈中元素出栈到局部变量表或者返回给方法调用者,也就是出栈/入栈操作。一个完整的方法执行期间往往包含多个这样出栈/入栈的过程。

动态连接

符号引用和直接引用在运行时进行解析和链接的过程

在一个class文件中,一个方法要调用其他方法,需要将这些方法的符号引用转化为其在内存地址中的直接引用,而符号引用存在于方法区中的运行时常量池。

Java虚拟机栈中,每个栈帧都包含一个指向运行时常量池中该栈所属方法的符号引用,持有这个引用的目的是为了支持方法调用过程中的动态连接(Dynamic Linking)

这些符号引用一部分会在类加载阶段或者第一次使用时就直接转化为直接引用,这类转化称为静态解析。另一部分将在每次运行期间转化为直接引用,这类转化称为动态连接。

3. 本地方法栈

本地方法栈是与虚拟机栈发挥的作用十分相似,区别是虚拟机栈执行的是Java方法(也就是字节码)服务,而本地方法栈则为虚拟机使用到的native方法服务。

4. 堆

所有线程共享的,目的是存放对象实例。

Java堆是垃圾收集器管理的主要区域。因此也叫GC堆。由于现在收集器基本都采用分代收集算法,所以Java堆中还可以细分为:新生代(Eden 空间、From Survivor 和 To Survivor 空间)和老年代

如果在堆中没有内存完成实例分配,并且堆也无法再扩展时,将会抛出OutOfMemoryError 异常

5. 方法区

方法区与Java堆一样,是各个线程共享的内存区域,它用于存储已被虚拟机加载的类信息、常量、静态变量、及时编译器编译后的代码等数据。

运行时常量池

是方法区的一部分,class 文件除了有类的字段、接口、方法等描述信息之外,还有一项信息是常量池,用于存放编译器生成的各种字面量和符号引用。

运行时常量池相对于Class文件常量池的一个重要特性是具备动态性Java语言并不要求常量一定只有编译期才能产生,也就是并非预置入Class文件中常量池的内容才能进入方法区运行时常量池,运行期间也可能将新的常量放入池中,比如说 String 的 intern()方法

参考文章

JVM 内存结构——运行时数据区

深入理解 JVM-内存模型(jmm)和 GC

Java 虚拟机—栈帧、操作数栈和局部变量表


标题:JVM内存模型
作者:SunnySky
地址:https://www.tianyang.pub/articles/2020/06/05/1591340076452.html

评论