首先要明确一个概念:操作数栈在栈帧中。我红色框圈起来的部分。

操作数栈的理解

每一个独立的栈针中除了包含局部变量表以外,还包含一个后进先出的操作数栈,也叫 表达式栈。

操作数栈在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈。

  • 某些字节码指令将值压入操作数栈,其余字节码指令将操作数取出栈,使用他们后再把结果压入栈。
  • 比如:执行复制,交换,求和等操作。

操作数栈的特点

  • 操作数栈,主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间。
  • 操作数栈就是jvm执行引擎的一个工作区,当一个方法开始执行的时候,一个新的栈帧也会随之被创建出来,这个方法的操作数栈是空的
  • 每一个操作数栈都会拥有一个明确的栈深度用于存储数值,其所需的最大深度在编译器就定义好了,保存在方法的code属性中,为max_stack的值。
  • 栈中的任何一个元素都是可以任意的java数据类型
    • 32bit的类型占用一个栈单位深度
    • 64bit的类型占用两个栈深度单位
  • 操作数栈并非采用访问索引的方式来进行数据访问的,而是只能通过标准的入栈push和出栈pop操作来完成一次数据访问
  • 如果被调用的方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中,并更新PC寄存器中下一条需要执行的字节码指令。
  • 操作数栈中的元素的数据类型必须与字节码指令的序列严格匹配,这由编译器在编译期间进行验证,同时在类加载过程中的类验证阶段的数据流分析阶段要再次验证。
  • 另外,我们说Java虚拟机的解释引擎是基于栈的执行引擎,其中的栈指的就是操作数栈。

操作数栈执行过程分析

先看代码:

下面以图的方式进行解析:

首先看字节码文件:

代码追踪

①PC寄存器是0,取出指令地址为0对应的操作指令,即把15放到操作数栈中,PC寄存器是2,执行指令地址为2的操作指令,即把操作数栈中的15放到局部变量表1的位置(isstore_1,就表示局部变量表1的位置)

② PC寄存器是3,取出指令地址为3对应的操作指令,即把8放到操作数栈中,PC寄存器是5,执行指令地址为5的操作指令,即把操作数栈中的8放到局部变量表2的位置(isstore_2,就表示局部变量表2的位置)

③iload1和iload2,表示从局部变量表中取出位置是1和2对应的数据,即15和8,放大局部变量表中

④接下来执行iadd指令,此时执行引擎就把字节码指令转化为机器指令,让cpu进行运算,然后执行istore_3指令,把结果放到局部变量表中3的位置,最后返回。

栈顶缓存技术

  • 基于栈式架构的虚拟机所使用的零地址指令(即不考虑地址,单纯入栈出栈)更加紧凑,但完成一项操作的时候必然需要使用更多的入栈和出栈指令,这同时也就意味着将需要更多的指令分派(instruction dispatch)次数和内存读/写次数
  • 由于操作数是存储在内存中的,因此频繁地执行内存读/写操作必然会影响执行速度。为了解决这个问题,HotSpot JVM的设计者们提出了栈顶缓存技术,将栈顶元素全部缓存在物理CPU的寄存器中,以此降低对内存的读/写次数,提升执行引擎的执行效率

好了,本篇文章结束,记得你的手动三连哦~

欧尼酱讲JVM(10)——操作数栈相关推荐

  1. 欧尼酱讲JVM(09)——虚拟机栈-变量槽slot

    这篇文章接着[JVM]运行时数据区-虚拟机栈  来写,虚拟机栈中提到了局部变量表,那么局部变量表又是存储什么内容呢? 关于Slot的理解 参数值的存放总是在局部变量数组的index0开始,到数组长度- ...

  2. 欧尼酱讲JVM(01)——整体概览(导航)

    从业这么久了,输入了很多东西,趁我还算不老,趁我还有精力,我觉得把我的知识和经验整理一番,输出出来. 那么首先就从JVM开始吧.我将从以下几个方面讲解JVM: 欧尼酱讲JVM(02)--类的加载过程 ...

  3. 欧尼酱讲JVM(17)——方法区详解有图有真相

    目录 位置图解 方法区的理解 方法区在哪里 方法区的基本理解 HotSpot中方法区的理解(演进过程) 方法区的内部结构 图解方法区内部结构 运行时常量池 class文件中常量池的理解 为什么需要常量 ...

  4. java的标量和聚合量_欧尼酱讲JVM(16)——如何基于逃逸分析进行代码优化

    代码优化是一个涉及面很广的"工程",但是今天呢,本姑娘主要给大家分享基于逃逸分析,如何给代码做优化.那么逃逸分析是什么呢?我前面的文章也仔细的讲解过了,这里就不过多的赘述了.有不明 ...

  5. 欧尼酱讲JVM(22)——分代收集算法

    目录 分代收集算法 HotSpot中的分代收集 年轻代 老年代 没有一种最好的算法吗?没有,没有最好只有最适合.具体问题具体分析! 上一篇文章<欧尼酱讲JVM(21)--垃圾回收相关算法> ...

  6. 欧尼酱讲JVM(07)——方法的栖身之所—虚拟机栈

    虚拟机栈的位置 虚拟机栈在运行时数据区中: 虚拟机栈出现的背景 由于跨平台性的设计,Java的指令都是根据栈来设计的,不同平台的CPU架构不同,所以不能设计为基于寄存器的. 优点是跨平台,指令集小,编 ...

  7. 欧尼酱讲JVM(11)——动态链接和常量池

    因为动态链接和运行时常量池有联系,所以先解释一下运行时常量池: 运行时常量池位于方法区(注意: JDK1.7 及之后版本的 JVM 已经将运行时常量池从方法区中移了出来,在 Java 堆(Heap)中 ...

  8. 欧尼酱讲JVM(18)——对象实例化内存布局与访问定位

    目录 对象的实例化 创建对象的几种方式 从字节码角度看对象的创建过程 对象创建的六个步骤 第一步:判断对象对应的类是否加载.链接.初始化 第二步:为这个对象分配内存 第三步:处理并发安全问题 第四步: ...

  9. 欧尼酱讲JVM(13)——本地方法栈

    位置图解 本地方法栈在运行时数据区中,三个灰色的部分是线程私有的. 本地方法栈作用 Java虚拟机栈用于管理Java方法的调用,而本地方法栈用于管理本地方法的调用. 本地方法栈是线程私有了,允许被线程 ...

最新文章

  1. 2003網域升級到2008網域以及遷移DNS
  2. 百度离职员工吐槽:整天除了工作还要演好戏,拍马屁,心太累!
  3. 因为那里面有我,也有你
  4. css笔记 - transform学习笔记(二)
  5. Jupyter notebook 运行环境创建和切换 (Win10+Anaconda)
  6. css文本超出隐藏 显示三个点
  7. JUC队列-ArrayBlockingQueue(一)
  8. CSS 属性 - 伪类和伪元素的区别
  9. [ZJJOI2013]K大数查询 整体二分
  10. android 中radiogroup滑动切换,巧妙实现缺角radiogroup控制多个fragment切换和滑动
  11. Spring AOP切入点与通知XML类型
  12. 没有run窗口_使用 Terminator 在一个窗口中运行多个终端 | Linux 中国
  13. 【区块链】以太坊truffle+web3+ganache简单实践
  14. spark SQL压缩入门
  15. vue.js学习02之vue-cli脚手架创建项目环境搭建
  16. 黑客们成功地在土豆上安装了Linux!
  17. mysql 序列自增长 恢复到1_MySQL查询结果另外自带一列自增序列号
  18. 详解高斯过程回归和核贝叶斯线性回归
  19. 详解百度快照劫持,小白必看篇
  20. Yuga Labs 收购 CryptoPunks 的始末

热门文章

  1. 万一 Github不让用了,Gitee同步指南请收好
  2. 基于MQTT和nodeMCU的音乐弹奏APP设计
  3. 内码转换表的来源与制作
  4. Kafka,amq,RabbitMq
  5. xilinx mmult
  6. Opencv速查函数列表
  7. bootstrap 点击图片弹出大图
  8. 数据库、数据仓库和数据湖的区别
  9. LTE Module User Documentation(翻译7)——无线环境地图(REM)、AMC 模型 和 CQI 计算...
  10. 【设计模式系列24】GoF23种设计模式总结及软件设计7大原则