「运行时数据区」——程序计数器、虚拟机栈( 四 )

参数表分配完毕之后 , 再根据方法体内定义的变量的顺序和作用域分配 。
我们知道类变量表有两次初始化的机会 , 第一次是在“ 准备阶段 ” , 执行系统初始化 , 对类变量设置零值 , 另一次则是在“ 初始化 ”阶段 , 赋予程序员在代码中定义的初始值 。
和类变量初始化不同的是 , 局部变量表不存在系统初始化的过程 , 这意味着一旦定义了局部变量则必须人为的初始化 , 否则无法使用 。
public void test(){int i;System.out.println(i);//报错 , 局部变量没有赋值不能使用 。 }在栈帧中 , 与性能调优关系最为密切的部分就是前面提到的局部变量表 。 在方法执行时 , 虚拟机使用局部变量表完成方法的传递 。
局部变量表中的变量也是重要的垃圾回收根节点 , 只要被局部变量表中直接或间接引用的对象都不会被回收 。 3.4 操作数栈(1)概述每一个独立的栈帧除了包含局部变量表以外 , 还包含一个后进先出(Last - In - First -Out)的 操作数栈, 也可以称之为 表达式栈 (Expression Stack) 。
操作数栈 , 在方法执行过程中 , 根据字节码指令 , 往栈中写入数据或提取数据 , 即 入栈(push)/出栈(pop)。

  • 某些字节码指令将值压入操作数栈 , 其余的字节码指令将操作数取出栈 。 使用它们后再把结果压入栈
  • 比如:执行复制、交换、求和等操作
操作数栈 ,主要用于保存计算过程的中间结果 , 同时作为计算过程中变量临时的存储空间。
操作数栈就是JVM执行引擎的一个工作区 , 当一个方法刚开始执行的时候 , 一个新的栈帧也会随之被创建出来 , 这个方法的操作数栈是 空 的 。
这个时候数组是有长度的 , 数组一旦创建 , 长度是不可变的 。
每一个操作数栈都会拥有一个明确的栈深度用于存储数值 , 其所需的最大深度在编译期就定义好了 , 保存在方法的Code属性中 , 为maxstack的值 。
栈中的任何一个元素都是可以任意的Java数据类型
  • 32bit的类型占用一个栈单位深度
  • 64bit的类型占用两个栈单位深度
操作数栈 并非采用访问索引的方式来进行数据访问, 而是只能通过标准的入栈和出栈操作来完成一次数据访问 。
如果被调用的方法带有返回值的话 , 其返回值将会被压入当前栈帧的操作数栈中 , 并更新PC寄存器中下一条需要执行的字节码指令 。
操作数栈中元素的数据类型必须与字节码指令的序列严格匹配 , 这由编译器在编译器期间进行验证 , 同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证 。 |
另外 , 我们说Java虚拟机的 解释引擎是基于栈的执行引擎, 其中的栈指的就是操作数栈 。
(2)代码追踪以下面代码为例子:
public void testAddOperation() {byte i = 15;int j = 8;int k = i + j;}使用javap 命令反编译class文件: javap -v 类名.class
0 bipush 15 2 istore_1 3 bipush 8 5 istore_2 6 iload_1 7 iload_2 8 iadd 9 istore_310 return从上面的代码我们可以知道 , 我们都是通过 bipush 对操作数 15 和 8进行入栈操作 , 同时使用的是 iadd方法进行相加操作 ,i -> 代表的是 int 类型的加法操作 。
Tips:byte、short、char、boolean 内部都是使用int型来进行保存的 。
执行流程如下所示:
首先执行第一条语句 , PC寄存器指向的是0 , 也就是指令地址为0 , 然后使用bipush让操作数15入栈 。
「运行时数据区」——程序计数器、虚拟机栈文章插图
执行完后 , 让PC + 1 , 指向下一行代码 , 下一行代码就是将操作数栈的元素存储到局部变量表 1的位置, 我们可以看到局部变量表的已经增加了一个元素 。
局部变量表也是从0开始的 , 但是因为0号位置存储的是this指针 , 这里省略书写了 。
然后PC+1 , 指向的是下一行 。 让操作数8也入栈 , 同时执行store操作 , 存入局部变量表中 。
「运行时数据区」——程序计数器、虚拟机栈文章插图
然后从局部变量表中 , 依次将数据放在操作数栈中 。
「运行时数据区」——程序计数器、虚拟机栈文章插图
然后将操作数栈中的两个元素执行相加操作 , 并存储在局部变量表3的位置 。
「运行时数据区」——程序计数器、虚拟机栈文章插图
最后PC寄存器的位置指向10 , 也就是return方法 , 则直接退出方法 。
(3)栈顶缓存技术栈顶缓存技术:Top Of Stack Cashing