zoukankan      html  css  js  c++  java
  • 第八篇 JVM之运行时数据区<4>: 操作数栈

       

     

      操作数栈(Operand Stack)是栈帧中一个先入后出的栈,同局部变量表一样,栈的最大深度在编译期间就已确定,并在运行期间也不会改变。JVM虚拟机的解释引擎是基于栈的执行引擎,其中的栈就是操作数栈。操作数栈其实可以理解为方法执行时变量的临时存储区,存储类型与局部变量表一致,其中byte、short、char都会转为int类型,32位类型所占的栈容量为1,64位类型则占用栈容量为2(如long和double)。

    一、执行原理

    public class OperandStackDemo {
        public int add() {
            int x = 2;
            int y = 4;
            int z = x + y;
            return z;
        }
    }
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_2
         1: istore_1
         2: iconst_4
         3: istore_2
         4: iload_1
         5: iload_2
         6: iadd
         7: istore_3
         8: iload_3
         9: ireturn

      以上面的简单代码为例,通过javap得到字节码文件中的Code属性部分,由Code的内容可以可知操作数栈最大深度为2,局部变量最大长度为4,Code中的字节码指令是由执行引擎解释执行,操作数栈中的元素的类型必须与字节码指令的序列相匹配,像上面出现的指令都是针对int类型操作,就不能去操作long类型的元素,JVM在编译时和类校验的数据流分析时都验证这一点,先了解Code中出现的几条JVM字节码指令:

    • iconst:将一个整型常量值(-1~5)推入操作数栈栈顶,不同范围的整型值对应指令不同,如bipush(-128~127)、sipush(-32768~32767)等。
    • istore:取出一个栈顶的整型常量值存入局部变量表。
    • iload:将局部变量表的元素放入操作数栈栈顶,可以看成和istore相反的操作。
    • iadd:取出栈顶两个整型值进行相加,。
    • ireturn:结束方法执行,并将栈顶整型常量值返回给方法调用者

      

      当一个Java方法开始执行时,首先线程会创建该方法的栈帧,栈帧创建空的操作数栈和局部变量表,执行过程中,会有各种指令往操作数栈中写入和读取内容,也就是出栈和入栈操作。如上图,是方法执行的过程中局部变量表、操作数栈及程序计数器的变化情况,由于是成员方法,所以执行开始时局部变量的0的索引位置会存储this变量,程序计数器中会存储将要执行字节码指令的地址,也就是0。

    • 1、执行偏移地址为0的iconst指令,后面2是跟随的整形常量值2,执行后,2进入操作数栈栈顶。
    • 2、执行偏移地址为1的istore指令,后面1是局部变量表的索引,取出栈顶元素2放入局部变量表索引为1的位置。
    • 3、3、4步骤与1、2作用相同。
    • 5、执行偏移地址为4的iload指令,后面1是局部变量表的索引,取出变量表索引为1的元素放入栈顶。
    • 6、同5
    • 7、执行偏移地址为6的iadd指令,取出操作栈栈顶的两个元素,进行相加并将结果放入栈顶。
    • 8、执行偏移地址为7的istore指令,取出栈顶元素放入局部变量表索引为3的位置。
    • 9、执行偏移地址为8的iload指令,取出局部变量表索引为3的元素放入栈顶。
    • 10、执行偏移地址为9的ireturn指令,返回栈顶元素给方法调用者。

    总结:

    • 1、操作数栈只能通过出栈和入栈,不能通过索引访问。
    • 2、栈元素类型与局部变量表一致,其中byte、short、char都会转为int类型,32位类型所占的栈容量为1,64位类型则占用栈容量为2。
    • 3、是方法执行时变量值的临时存储区
  • 相关阅读:
    协同过滤
    深度学习中 epoch,[batch size], iterations概念解释
    如何查看Python内置模块的实现代码
    机器学习/数据挖掘/算法岗位
    算法工程师B
    算法工程师A
    web性能测试基本性能指标
    Loadrunner11不能调用IE8解决方法大全
    抓取Android应用的log
    关于字符latin capital letter sharp s "ß"( U+1E9E)显示的问题
  • 原文地址:https://www.cnblogs.com/zhexuejun/p/15509161.html
Copyright © 2011-2022 走看看