JVM运行时数据区一

avatar
作者
筋斗云
阅读量:0

运行时数据区-总览

线程不共享(安全,线程结束回收)

  • 程序计数器
  • Java虚拟机栈(在实现上和本地方法栈是使用的一个栈)
  • 本地方法栈

线程共享(不安全)

  • 方法区

程序计数器

  • 程序计数器(Program Counter Register)也叫PC寄存器,每个线程会通过程序计数器记录当前要执行的字节码指令的地址
  • 在加载阶段,虚拟机将字节码文件中的指令读取到内存之后,会将原文件中的偏移量转换成内存地址。每一条字节码指令都会拥有一个内存地址
  • 在代码执行过程中,程序计数器会记录下一行字节码指令的地址。当执行完当前指令之后,虚拟机的执行引擎根据程序计数器执行下一条指令
  • 程序计数器可以控制程序指令的进行,实现分支、跳转、异常等逻辑
  • 在多线程执行情况下,java虚拟机需要通过程序计数器记录CPU切换前解释执行的那一句指令并继续解释执行

问题:程序计数器在运行时会出现内存溢出吗

  • 内存溢出指的是程序在使用某一块内存区域时,存放的数据需要占用的内存大小超过了虚拟机能够提供的内存上限
  • 因为每个线程只存储一个固定长度的内存地址,程序计数器是不会发生内存溢出的
  • 程序员无需对程序计数器做任何处理

Java虚拟机栈

  • 采用栈的数据结构来管理方法调用中的基本数据,先进后出First In Last Out,每一个方法的调用使用一个栈帧(Stack Frame)来保存
  • Java虚拟机栈随着线程的创建而创建,而回收则会在线程的销毁时进行。由于方法可能会在不同线程中执行,每个线程都会包含一个自己的虚拟机栈

栈帧

  • 局部变量表
    • 局部变量表的作用是在运行过程中存放所有的局部变量
    • 栈帧中的局部变量表是一个数组,数组中每一个位置称之为槽(slot),long和double类型占用两个槽,其他类型占用一个槽
    • 方法参数也会保存在局部变量表中,其顺序与方法中参数定义的顺序一致
    • 局部变量表保存的内容有:实例方法的this对象、方法的参数、方法体中声明的局部变量
    • 为了节省空间,局部变量表中的槽是可以复用的,一旦某个局部变量不再生效,当前槽就可以再次被使用
  • 操作数栈
    • 操作数栈是栈帧中虚拟机在执行指令过程中用来存放临时数据的一块区域
    • 他是一致栈式的数据结构,如果一条指令将一个值压入操作数栈,则后面的指令可以弹出并使用该值
    • 在编译期就可以确定操作数栈的最大深度,从而在执行时正确的分配内存大小
  • 帧数据
    • 帧数据主要包含动态链接、方法出口、异常表的引用
    • 当前类的字节码指令使用了其他类的属性或者方法时,需要将符号引用(编号)转换成对应的运行时常量池中的内存地址。动态链接就保存了编号到运行时常量池的内存地址的映射关系
    • 方法出口指的是方法在正确或者异常结束时,当前栈帧会被弹出,同时程序计数器应该指向上一个栈帧中的下一条指令的地址。所以在当前栈帧中,需要存储此方法的出口地址
    • 异常表存放的是代码中异常的处理信息,包含了异常捕获的生效范围以及异常发生后跳转到的字节码指令位置

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!