JVM内存结构深度解析,有哪些关键点需要深入理解?

2026-05-28 03:371阅读0评论SEO教程
  • 内容介绍
  • 文章标签
  • 相关推荐

本文共计1967个文字,预计阅读时间需要8分钟。

JVM内存结构深度解析,有哪些关键点需要深入理解?

《免费领取 JVM 学习资料——《深入理解 JVM(一)——JVM 内存结构之官方文档解读》+ 在上一篇文章中,我们通过 JDK 官方说明文档,对 JVM 内存结构进行了初步的了解。接下来,我们将继续深入探讨 JVM 的内存结构,并通过官方文档进行解读。》

》》》》》》》》》文章末尾免费领取 JVM 学习资料《《《《《《《《《

在上一篇文章​​《深入理解 JVM(一)-JVM 内存结构之官方文档解读》​​中,通过 JDK 官方说明文档,我们对 JVM 结构有了一个初步认识,接下来我们通过自己的理解来深入剖析下 JVM 内存结构。

​JVM内存结构

1.PC寄存器

1、当前线程所执行的字节码行号指示器。

2、每个线程都有一个自己的PC计数器。

3、线程私有的,生命周期与线程相同,随JVM启动而生,JVM关闭而死。

4、线程执行Java方法时,记录其正在执行的虚拟机字节码指令地址。

5、线程执行Native方法时,计数器记录为空(Undefined)。

6、唯一在Java虚拟机规范中没有规定任何OutOfMemoryError情况区域。

2.Java虚拟机栈

存储栈帧(包括局部变量表、操作数栈、动态链接、方法出口),保存局部变量和尚未计算好的结果,线程私有的,生命周期与线程相同,随JVM启动而生,JVM关闭而死。

3.堆

Java堆是被所有线程共享的最大的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存(还可能栈上分配,系列文章后续会详细说明)。

4.方法区

方法区和Java堆一样,为多个线程共享,它用于存储类信息、常量、静态常量和即时编译后的代码等数据。

5.运行时常量池

运行时常量池是方法区的一部分,Class文件中除了有类的版本、字段、方法和接口等描述信息外, 还有一类信息是常量池,用于存储编译期间生成的各种字面量和符号引用。

6.本地方法栈

本地方法栈和Java虚拟机栈发挥的作用非常相似,主要区别是Java虚拟机栈执行的是Java方法服务,而本地方法栈执行Native方法服务(通常用C编写)。

7.直接内存

直接内存不属于虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。Java NIO允许Java程序直接访问直接内存,通常直接内存的速度会优于Java堆内存。因此,对于读写频繁、性能要求高的场景,可以考虑使用直接内存。

栈帧结构

1. 局部变量表

局部变量表是一组变量值的存储空间,用于存储方法参数和局部变量。在 Class 文件的方法表的 Code 属性的 max_locals 指定了该方法所需局部变量表的最大容量。局部变量表在编译期间分配内存空间,可以存放编译期的各种变量类型:

1. 基本数据类型:boolean, byte, char, short, int, float, long, double 等 8 种;

2. 对象引用类型:reference,指向对象起始地址的引用指针;

3. 返回地址类型:returnAddress,返回地址的类型。

变量槽 (Variable Slot):

变量槽是局部变量表的最小单位,规定大小为 32 位。对于 64 位的 long 和 double 变量而言,虚拟机会为其分配两个连续的 Slot 空间。

2. 操作数栈

在Class文件的Code属性的max_stacks指定了执行过程中最大的栈深度,

1. 和局部变量表一样,操作数栈也是一个以 32 字长为单位的数组。

2. 虚拟机在操作数栈中可存储的数据类型:int、long、float、double、reference 和 returnType 等类型 (对于 byte、short 以及 char 类型的值在压入到操作数栈之前,也会被转换为 int)。

3. 和局部变量表不同的是,它不是通过索引来访问,而是通过标准的栈操作—压栈和出栈来访问。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用。

虚拟机把操作数栈作为它的工作区 —— 大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

begin
iload_0 // push the int in local variable 0 onto the stack
iload_1 // push the int in local variable 1 onto the stack
iadd // pop two ints, add them, push result
istore_2 // pop int, store into local variable 2
end

在这个字节码序列里,前两个指令 iload_0和 iload_1 将存储在局部变量表中索引为 0 和 1 的整数压入操作数栈中,其后 iadd 指令从操作数栈中弹出那两个整数相加,再将结果压入操作数栈。第四条指令 istore_2 则从操作数栈中弹出结果,并把它存储到局部变量表索引为 2 的位置。

下图详细表述了这个过程中局部变量表和操作数栈的状态变化 (图中没有使用的局部变量表和操作数栈区域以空白表示)。

3. 动态链接

每个栈帧都包含一个指向运行时常量池中所属的方法引用,持有这个引用是为了支持方法调用过程中的动态链接。

Class 文件的常量池中存在有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用:

1. 静态解析:一部分会在类加载阶段或第一次使用的时候转化为直接引用(如 final、static 域等),称为静态解析,

2. 动态解析:另一部分将在每一次的运行期间转化为直接引用,称为动态链接。

4. 方法返回地址

当一个方法开始执行以后,只有两种方法可以退出当前方法:

1. 正常返回:当执行遇到返回指令,会将返回值传递给上层的方法调用者,这种退出的方式称为正常完成出口 (Normal Method Invocation Completion),一般来说,调用者的 PC 计数器可以作为返回地址。

2. 异常返回:当执行遇到异常,并且当前方法体内没有得到处理,就会导致方法退出,此时是没有返回值的,称为异常完成出口 (Abrupt Method Invocation Completion),返回地址要通过异常处理器表来确定。

JVM内存结构深度解析,有哪些关键点需要深入理解?

当一个方法返回时,可能依次进行以下 3 个操作:

  • 恢复上层方法的局部变量表和操作数栈。
  • 把返回值压入调用者栈帧的操作数栈。
  • 将 PC 计数器的值指向下一条方法指令位置。

  • 微信搜索 “Java 码仔”,回复 “jvm” 免费领取 JVM 学习资料

    本文共计1967个文字,预计阅读时间需要8分钟。

    JVM内存结构深度解析,有哪些关键点需要深入理解?

    《免费领取 JVM 学习资料——《深入理解 JVM(一)——JVM 内存结构之官方文档解读》+ 在上一篇文章中,我们通过 JDK 官方说明文档,对 JVM 内存结构进行了初步的了解。接下来,我们将继续深入探讨 JVM 的内存结构,并通过官方文档进行解读。》

    》》》》》》》》》文章末尾免费领取 JVM 学习资料《《《《《《《《《

    在上一篇文章​​《深入理解 JVM(一)-JVM 内存结构之官方文档解读》​​中,通过 JDK 官方说明文档,我们对 JVM 结构有了一个初步认识,接下来我们通过自己的理解来深入剖析下 JVM 内存结构。

    ​JVM内存结构

    1.PC寄存器

    1、当前线程所执行的字节码行号指示器。

    2、每个线程都有一个自己的PC计数器。

    3、线程私有的,生命周期与线程相同,随JVM启动而生,JVM关闭而死。

    4、线程执行Java方法时,记录其正在执行的虚拟机字节码指令地址。

    5、线程执行Native方法时,计数器记录为空(Undefined)。

    6、唯一在Java虚拟机规范中没有规定任何OutOfMemoryError情况区域。

    2.Java虚拟机栈

    存储栈帧(包括局部变量表、操作数栈、动态链接、方法出口),保存局部变量和尚未计算好的结果,线程私有的,生命周期与线程相同,随JVM启动而生,JVM关闭而死。

    3.堆

    Java堆是被所有线程共享的最大的一块内存区域,在虚拟机启动时创建。此内存区域的唯一目的就是存放对象实例,几乎所有的对象实例都在这里分配内存(还可能栈上分配,系列文章后续会详细说明)。

    4.方法区

    方法区和Java堆一样,为多个线程共享,它用于存储类信息、常量、静态常量和即时编译后的代码等数据。

    5.运行时常量池

    运行时常量池是方法区的一部分,Class文件中除了有类的版本、字段、方法和接口等描述信息外, 还有一类信息是常量池,用于存储编译期间生成的各种字面量和符号引用。

    6.本地方法栈

    本地方法栈和Java虚拟机栈发挥的作用非常相似,主要区别是Java虚拟机栈执行的是Java方法服务,而本地方法栈执行Native方法服务(通常用C编写)。

    7.直接内存

    直接内存不属于虚拟机运行时数据区的一部分,也不是Java虚拟机规范中定义的内存区域。Java NIO允许Java程序直接访问直接内存,通常直接内存的速度会优于Java堆内存。因此,对于读写频繁、性能要求高的场景,可以考虑使用直接内存。

    栈帧结构

    1. 局部变量表

    局部变量表是一组变量值的存储空间,用于存储方法参数和局部变量。在 Class 文件的方法表的 Code 属性的 max_locals 指定了该方法所需局部变量表的最大容量。局部变量表在编译期间分配内存空间,可以存放编译期的各种变量类型:

    1. 基本数据类型:boolean, byte, char, short, int, float, long, double 等 8 种;

    2. 对象引用类型:reference,指向对象起始地址的引用指针;

    3. 返回地址类型:returnAddress,返回地址的类型。

    变量槽 (Variable Slot):

    变量槽是局部变量表的最小单位,规定大小为 32 位。对于 64 位的 long 和 double 变量而言,虚拟机会为其分配两个连续的 Slot 空间。

    2. 操作数栈

    在Class文件的Code属性的max_stacks指定了执行过程中最大的栈深度,

    1. 和局部变量表一样,操作数栈也是一个以 32 字长为单位的数组。

    2. 虚拟机在操作数栈中可存储的数据类型:int、long、float、double、reference 和 returnType 等类型 (对于 byte、short 以及 char 类型的值在压入到操作数栈之前,也会被转换为 int)。

    3. 和局部变量表不同的是,它不是通过索引来访问,而是通过标准的栈操作—压栈和出栈来访问。比如,如果某个指令把一个值压入到操作数栈中,稍后另一个指令就可以弹出这个值来使用。

    虚拟机把操作数栈作为它的工作区 —— 大多数指令都要从这里弹出数据,执行运算,然后把结果压回操作数栈。

    begin
    iload_0 // push the int in local variable 0 onto the stack
    iload_1 // push the int in local variable 1 onto the stack
    iadd // pop two ints, add them, push result
    istore_2 // pop int, store into local variable 2
    end

    在这个字节码序列里,前两个指令 iload_0和 iload_1 将存储在局部变量表中索引为 0 和 1 的整数压入操作数栈中,其后 iadd 指令从操作数栈中弹出那两个整数相加,再将结果压入操作数栈。第四条指令 istore_2 则从操作数栈中弹出结果,并把它存储到局部变量表索引为 2 的位置。

    下图详细表述了这个过程中局部变量表和操作数栈的状态变化 (图中没有使用的局部变量表和操作数栈区域以空白表示)。

    3. 动态链接

    每个栈帧都包含一个指向运行时常量池中所属的方法引用,持有这个引用是为了支持方法调用过程中的动态链接。

    Class 文件的常量池中存在有大量的符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用:

    1. 静态解析:一部分会在类加载阶段或第一次使用的时候转化为直接引用(如 final、static 域等),称为静态解析,

    2. 动态解析:另一部分将在每一次的运行期间转化为直接引用,称为动态链接。

    4. 方法返回地址

    当一个方法开始执行以后,只有两种方法可以退出当前方法:

    1. 正常返回:当执行遇到返回指令,会将返回值传递给上层的方法调用者,这种退出的方式称为正常完成出口 (Normal Method Invocation Completion),一般来说,调用者的 PC 计数器可以作为返回地址。

    2. 异常返回:当执行遇到异常,并且当前方法体内没有得到处理,就会导致方法退出,此时是没有返回值的,称为异常完成出口 (Abrupt Method Invocation Completion),返回地址要通过异常处理器表来确定。

    JVM内存结构深度解析,有哪些关键点需要深入理解?

    当一个方法返回时,可能依次进行以下 3 个操作:

  • 恢复上层方法的局部变量表和操作数栈。
  • 把返回值压入调用者栈帧的操作数栈。
  • 将 PC 计数器的值指向下一条方法指令位置。

  • 微信搜索 “Java 码仔”,回复 “jvm” 免费领取 JVM 学习资料