《剑指JVM》——第4章 操作数栈——虚拟机栈4——运行时数据区篇7

🌈hello,你好鸭,我是Ethan,西安电子科技大学大三在读,很高兴你能来阅读。

✔️目前博客主要更新Java系列、项目案例、计算机必学四件套等。
🏃人生之义,在于追求,不在成败,勤通大道。加油呀!

🔥个人主页:Ethan Yankang
🔥推荐:史上最强八股文||一分钟看完我的几百篇博客

🔥温馨提示:划到文末发现专栏彩蛋   点击这里直接传送

🔥本篇概览:详细讲解了虚拟机栈的组成部分——操作数栈的详细信息。🌈⭕🔥


【计算机领域一切迷惑的源头都是基本概念的模糊,算法除外】


🔥 《剑指JVM》序言-CSDN博客

🔥 《剑指JVM》全书-CSDN博客


🌈引出

前一篇章:《剑指JVM》——第4章 局部变量表——虚拟机栈3——运行时数据区篇6-CSDN博客


1.操作数栈的引出:

每一个独立的栈帧中除了包含局部变量表以外,还包含一个后进先出的操作数栈,也可以称为表达式栈(Expression Stack)。
操作数栈也是栈帧中重要的内容之一,它主要用于保存计算过程的中间结果,同时作为算过程中变量临时的存储空间。



2.操作数栈的工作:

我们说JVM 的解释引擎是基于栈的执行引擎,其中的栈指的就是操作数栈

java中的任何指令执行时,都会先将指令操作的数入操作数栈

某些字节码指令将值压入操作数栈,其余的字节码指令将操作数从栈中取出,比如,执行复制、交换、求和等操作。使用它们后再把结果压入栈,如图4-19所示,2和3分别出栈,经过 iadd 指令执行后再入栈。

操作数栈就是JVM执行引擎的一个工作区,当一个方法刚开始执行的时候,一个新的栈帧也会随之被创建出来,这个方法的操作数栈是空的。


操作数栈并非采用访问索引的方式来进行数据访问的,(而是只能通过标准的入栈(push)和出栈(pop)操作来完成一次数据访问)。

如果被调用的方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中,并更新程序计数器中下一条需要执行的字节码指令。操作数栈中元素的数据类型必须与字节码指令的序列严格匹配,这由编译器在编译期间进行验证,同时在类加载过程中的类检验阶段的数据流分析阶段要再次验证。

另外,我们说JVM 的解释引擎是基于栈的执行引擎,其中的栈指的就是操作数栈,如代码清单 4-9所示。


3.操作数栈字节码演示:

/*************************************************************************
    > File Name: OperandStackTest.java
    > Author: ma6174
    > Mail: ma6174@163.com 
    > Created Time: 2024/7/15 6:56:51
 ************************************************************************/
public class OperandStackTest {
    public void testAddOperation() {
        byte i = 2;
        int j = 3;
        int k = (int)i + j;
    }
}

使用 javap 命令反编译 class 文件:javap-v类名.class,部分结果如下。

  public void testAddOperation();
    descriptor: ()V
    flags: (0x0001) ACC_PUBLIC
    Code:
      stack=2, locals=4, args_size=1
         0: iconst_2
         1: istore_1
         2: iconst_3
         3: istore_2
         4: iload_1
         5: iload_2
         6: iadd
         7: istore_3
         8: return

字节码执行步骤追踪如下所示。
(1)由“iconst_2”指令将数值2从byte类型转换为int类型后压入操作数栈的栈顶(对于byte、short 和 char 类型的值在入栈之前,会被转换为int 类型),如图 4-20 所示。

(2)当成功入栈后,“istore_1”指令便会负责将栈顶元素出栈并存储在局部变量表中访间索引为1的 slot 上,如图 4-21 所示。

(3)接下来执行“iconst_3”指令将数值3压入栈顶,如图 4-22 所示。

(4)通过“istore_2”指令将栈顶元素出栈,并存储在局部变量表中索引为2的slot上,如图 4-23 所示。

(5)“iload_1”指令会将局部变量表中访问索引为1的slot上的数值2重新压入操作数栈的栈顶,如图 4-24 所示。
(6)“iload_2”指令会将局部变量表中访问索引为2的slot上的数值3重新压入操作数栈的栈顶,如图 4-25 所示。

(7)紧接着“iadd”指令便会将这两个数值出栈,执行加法运算后再将运行结果重新压入栈顶,如图 4-26 所示。
(8)“istore_3”会将运行结果出栈并存储在局部变量表中访问索引为3的slot上,如图4-27所示。最后“return”指令的作用就是方法执行完成之后的返回操作。

 



💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖💖

热门专栏推荐

🌈🌈计算机科学入门系列                     关注走一波💕💕

🌈🌈CSAPP深入理解计算机原理        关注走一波💕💕

🌈🌈微服务项目之黑马头条                 关注走一波💕💕

🌈🌈redis深度项目之黑马点评            关注走一波💕💕

🌈🌈JAVA面试八股文系列专栏           关注走一波💕💕

🌈🌈JAVA基础试题集精讲                  关注走一波💕💕   

🌈🌈代码随想录精讲200题                  关注走一波💕💕


总栏

🌈🌈JAVA基础要夯牢                         关注走一波💕💕  

🌈🌈​​​​​​JAVA后端技术栈                          关注走一波💕💕  

🌈🌈JAVA面试八股文​​​​​​                          关注走一波💕💕  

🌈🌈JAVA项目(含源码深度剖析)    关注走一波💕💕  

🌈🌈计算机四件套                               关注走一波💕💕  

🌈🌈数据结构与算法                           ​关注走一波💕💕  

🌈🌈必知必会工具集                           关注走一波💕💕

🌈🌈书籍网课笔记汇总                       关注走一波💕💕         



📣非常感谢你阅读到这里,如果这篇文章对你有帮助,希望能留下你的点赞👍 关注❤收藏✅ 评论💬,大佬三连必回哦!thanks!!!
📚愿大家都能学有所得,功不唐捐!

  • 8
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值