深入理解JVM虚拟机第二十二篇:详解JVM当中与操作数栈相关的字节码指令

大神链接:作者有幸结识技术大神孙哥为好友,获益匪浅。现在把孙哥视频分享给大家。

孙哥链接:孙哥个人主页
作者简介:一个颜值99分,只比孙哥差一点的程序员
本专栏简介:话不多说,让我们一起干翻JVM

本文章简介:话不多说,让我们讲清楚JVM当中与操作数栈相关的字节码指令

文章目录

一: 操作数栈字节码指令

1:编写源码

2:javap解释整理字节码

3:通过jclasslib查看字节码指令

二:字节码分析

1:最全字节码指令分析

2:面试题


一: 操作数栈字节码指令

1:编写源码

public class OperandStackTest {public void testAndOperation(){byte i = 15;int j = 8;int k = i+j;}
}

2:javap解释整理字节码

        想要查看字节码文件呢,我们有两种方式,第一种就是直接进行javap,第二种就是使用jclasslib进行查看,我们先使用第一种。

PS D:\code\study\hadoop\shit\target\classes> javap -verbose .\OperandStackTest.class
Classfile /D:/code/study/hadoop/shit/target/classes/OperandStackTest.classLast modified 2023年11月9日; size 421 bytesSHA-256 checksum 487149a1edc4d19af0b1fe2369086c27c8765ff5e011491d1028d4f6cf1d9746Compiled from "OperandStackTest.java"
public class OperandStackTestminor version: 0major version: 52flags: (0x0021) ACC_PUBLIC, ACC_SUPERthis_class: #2                          // OperandStackTestsuper_class: #3                         // java/lang/Objectinterfaces: 0, fields: 0, methods: 2, attributes: 1
Constant pool:#1 = Methodref          #3.#19         // java/lang/Object."<init>":()V#2 = Class              #20            // OperandStackTest#3 = Class              #21            // java/lang/Object#4 = Utf8               <init>#5 = Utf8               ()V#6 = Utf8               Code#7 = Utf8               LineNumberTable#8 = Utf8               LocalVariableTable#9 = Utf8               this#10 = Utf8               LOperandStackTest;#11 = Utf8               testAndOperation#12 = Utf8               i#13 = Utf8               B#14 = Utf8               j#15 = Utf8               I#16 = Utf8               k#17 = Utf8               SourceFile#18 = Utf8               OperandStackTest.java#19 = NameAndType        #4:#5          // "<init>":()V#20 = Utf8               OperandStackTest#21 = Utf8               java/lang/Object
{public OperandStackTest();descriptor: ()Vflags: (0x0001) ACC_PUBLICCode:stack=1, locals=1, args_size=10: aload_01: invokespecial #1                  // Method java/lang/Object."<init>":()V4: returnLineNumberTable:line 1: 0LocalVariableTable:Start  Length  Slot  Name   Signature0       5     0  this   LOperandStackTest;public void testAndOperation();descriptor: ()Vflags: (0x0001) ACC_PUBLICCode:stack=2, locals=4, args_size=10: bipush        152: istore_13: bipush        85: istore_26: iload_17: iload_28: iadd9: istore_310: returnLineNumberTable:line 3: 0line 4: 3line 5: 6line 6: 10LocalVariableTable:Start  Length  Slot  Name   Signature0      11     0  this   LOperandStackTest;3       8     1     i   B6       5     2     j   I10       1     3     k   I
}
SourceFile: "OperandStackTest.java"

3:通过jclasslib查看字节码指令

        首先进行recompile Java文件为字节码文件,然后我们在idea的view下找到这个:

        show ByteCode with JclassLib:

        最终显示结果如下:

二:字节码分析

1:最全字节码指令分析

public class OperandStackTest {public void testAndOperation(){byte i = 15;int j = 8;int k = i+j;}
}
 0 bipush 152 istore_13 bipush 85 istore_26 iload_17 iload_28 iadd9 istore_3
10 return

         bipush将15这个值push到了操作数栈中,此时我们的操作数栈就有了第一个值。我们需要回顾一下:byte、short、char、boolean、int类型在声明之后往数组中进行存放的时候都会保存为int类型。也就是说虽然定义的是byte类型,但是存放到数组中就是int类型

        栈帧在调用之初,栈帧被创建完成,其中的操作数栈和局部变量表是空的。PC寄存器中存放着第一条要执行的指令的地址。

        istore_1将这个值从操作数栈放到了局部变量表中索引为1的位置,为什么不是0呢?因为这不是一个静态方法,索引为零的位置存放的是this。

        此时的操作数栈就成了空,这是一个出栈的操作。过程中会修改PC寄存器中的索引值为下一条命令的索引值。

       过程中会修改PC寄存器中的索引值为下一条命令的索引值。

       同样的道理,8也会经过bipush和istore_2,然后最终的结果如下:

        iload_1和iload_2命令会将变量中索引为1,2的数据取出来分别放到局部变量表中

        最终的运行结果如下:

        紧接着会进行一个iadd命令,这个命令呢会使数据进行出栈,然后相加。值得注意的是,字节码指令需要被翻译为机器指令,机器指令操作CPU进行相加。然后将结果23放到操作数栈当中。

        运行结果如下:

        

        最终,istore_3将这个值从操作数栈放到了局部变量表中索引为3的位置, 此时的操作数栈就成了空,这是一个出栈的操作。过程中会修改PC寄存器中的索引值为下一条命令的索引值。

        最终的运行结果如下:

        我们也注意到,局部变量表长度为4,操作数栈深度为2(看javap的结果),这也是与图中可以对应上的,唯一区别的是局部变量表中的因为篇幅原因,this的位置也就是索引为0的变量槽没有展示出来。 

        补充说明:

        我们注意到bipush是将一个byte类型的数据push到操作数栈中基于int类型进行存储,还有sipush,这个字节码指令的含义是将short类型的数据push到操作数栈中基于int类型进行存储。

        如果方法有返回值,那么最终的字节码指令将由return会变成ireturn。也就是将值做了一个返回,这个栈帧就结束了,另外一个调用此方法的栈帧会立即调用一个aload_x这样的一个操作,将上一个方法的返回值加载到此栈帧的操作数栈中。

    public int getSum(){int m = 10;int n = 20;int k = m+n;return k;}public void testGetSum(){//aload_0获取上一个栈帧返回的结果,并保存在操作数栈中。int i = getSum();int j = 10;}

2:面试题

        i++ 和 ++j的区别是什么?

       此问题,后续我们在字节码文章中会跟大家进行探讨

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.rhkb.cn/news/185737.html

如若内容造成侵权/违法违规/事实不符,请联系长河编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++ —— map 和 multimap

一、map 1.介绍 1. map是关联容器&#xff0c;它按照特定的次序(按照key来比较)存储由键值key和值value组合而成的元 素。 2. 在map中&#xff0c;键值key通常用于排序和惟一地标识元素&#xff0c;而值value中存储与此键值key关联的内容。键值key和值value的类型可能不同&am…

【Linux精讲系列】——vim详解

​作者主页 &#x1f4da;lovewold少个r博客主页 ⚠️本文重点&#xff1a;c入门第一个程序和基本知识讲解 &#x1f449;【C-C入门系列专栏】&#xff1a;博客文章专栏传送门 &#x1f604;每日一言&#xff1a;宁静是一片强大而治愈的神奇海洋&#xff01; 目录 目录 ​作者…

【教3妹学编程-算法题】 在树上执行操作以后得到的最大分数

3妹&#xff1a;2哥&#xff0c;今日都立冬了&#xff0c; 可是天气一点都不冷。 2哥 : 立冬了&#xff0c;晚上要不要一起出去吃饺子&#xff1f;&#x1f95f; 3妹&#xff1a;好呀好呀&#xff0c;2哥请吃饺子喽 2哥 : 歪歪&#xff0c;我说的是一起出去吃&#xff0c;没说我…

CSS实现鼠标移至图片上显示遮罩层及文字效果

效果图&#xff1a; 1、将遮罩层html代码与图片放在一个div 我是放在 .proBK里。 <div class"proBK"><img src"../../assets/image/taskPro.png" class"proImg"><div class"imgText"><h5>用户在线发布任务&l…

另辟蹊径者 PoseiSwap:背靠潜力叙事,构建 DeFi 理想国

前不久&#xff0c;灰度在与 SEC 就关于 ETF 受理的诉讼案件中&#xff0c;以灰度胜诉告终。灰度的胜利&#xff0c;也被加密行业看做是加密 ETF 在北美地区阶段性的胜利&#xff0c; 该事件也带动了加密市场的新一轮复苏。 此前&#xff0c;Nason Smart Money 曾对加密市场在 …

SHCTF-校外赛道

SHCTF-校外赛道 [WEEK1]babyRCE 1 (1)more:一页一页的显示档案内容2 (2)less:与 more 类似&#xff0c;但是比 more 更好的是&#xff0c;他可以[pg dn][pg up]翻页3 (3)head:查看头几行4 (4)tac:从最后一行开始显示&#xff0c;可以看出 tac 是 cat 的反向显示5 (5)tail:查看…

【Springboot】Vue3-Springboot引入JWT实现登录校验以及常见的错误解决方案

文章目录 前言一、JWT简单介绍二、token校验设计思路三、使用步骤Springboot部署JWT引入依赖&#xff1a;创建登录实体类后端&#xff1a;LoginController.java路由守卫函数 四、问题 前言 项目版本&#xff1a; 后端&#xff1a; Springboot 2.7、 Mybatis-plus、Maven 3.8.1…

JavaFX入门和网格布局面板的使用,Dao层交互,舞台与场景切换以及其他控件的使用

网格布局 将整个面板划分为若干个格子 , 每个格子的大小是一样的 , 每个格子中可以放置一个控件&#xff08;布局&#xff09; , 类似于表格的方式。在网格布局 中放入控件的时候 , 还需要指定位置。 GridPane gridPane new GridPane(); 我们将要排出这个布局 , 也就是登陆页…

JVM之jinfo虚拟机配置信息工具

jinfo虚拟机配置信息工具 1、jinfo jinfo&#xff08;Configuration Info for Java&#xff09;的作用是实时地查看和调整虚拟机的各项参数。 使用jps -v 可以查看虚拟机启动时显示指定的参数列表&#xff0c;但是如果想知道未被显示指定的参数的系统默认值&#xff0c;除 …

MySQL的高阶语句

数据库的权限一般很小&#xff0c;工作中使用最多的场景就是查 排序、分组、子查询、视图、多表连接查询&#xff08;左连接、右连接、内连接&#xff09; create TABLE info ( id int(4) primary key, NAME varchar(5) not null, score decimal(5,2), address varchar(20)…

在 Gorm 中学习分页和排序

一个全面的指南&#xff0c;教您在 GORM 中实现分页和排序&#xff0c;以实现高效的数据检索和展示 高效的数据检索和展示是应用程序开发的关键方面。GORM&#xff0c;强大的 Go 对象关系映射库&#xff0c;为开发人员提供了强大的工具来实现这一目标。在本指南中&#xff0c;…

【数据结构】二叉树的遍历递归算法详解

二叉树的遍历 &#x1f4ab;二叉树的结点结构定义&#x1f4ab;创建一个二叉树结点&#x1f4ab;在主函数中手动创建一颗二叉树&#x1f4ab;二叉树的前序遍历&#x1f4ab;调用栈递归——实现前序遍历&#x1f4ab;递归实现中序和后序遍历 &#x1f4ab;二叉树的结点结构定义 …

百面深度学习-循环神经网络

循环神经网络 什么是循环神经网络&#xff1f; 循环神经网络&#xff08;Recurrent Neural Network&#xff0c;RNN&#xff09;是一类用于处理序列数据的神经网络。你可以将它想象成一个机器&#xff0c;它不仅考虑当前的输入&#xff0c;还考虑之前接收过的输入。这使得它非…

本地生活餐饮视频怎么拍摄能有更多流量?如何批量生产呢?

本地生活近几年特别的火&#xff0c;所以到现在各类内容雷同性也比较高&#xff0c;视频缺少新的创意和玩法&#xff0c;像餐饮店的视频&#xff0c;大部分都是拍顾客进门、拍餐饮店座无虚席的实景……作为用户&#xff0c;其实早就已经看腻了。 今天推荐本地生活餐饮店商家拍…

b 树和 b+树的理解

&#xff08;本文引自mic老师面试文档&#xff09; 数据结构与算法问题&#xff0c;困扰了无数的小伙伴。 很多小伙伴对数据结构与算法的认知有一个误区&#xff0c;认为工作中没有用到&#xff0c;为什么面试要问&#xff0c;问了能解决实际问题&#xff1f; 图灵奖获得者&am…

手把手教你:LLama2原始权重转HF模型

LLama2是meta最新开源的语言大模型&#xff0c;训练数据集2万亿token&#xff0c;上下文长度由llama的2048扩展到4096&#xff0c;可以理解和生成更长的文本&#xff0c;包括7B、13B和70B三个模型&#xff0c;在各种基准集的测试上表现突出&#xff0c;该模型可用于研究和商业用…

Android sqlite 使用简介

进行Android应用开发时经常会用到数据库。Android系统支持sqlite数据库&#xff0c;在app开发过程中很容易通过SQLiteOpenHelper使用数据库&#xff0c;SQLiteOpenHelper依赖于Context对象&#xff0c;但是基于uiatomator1.0和Java程序等无法获取Context的应用如何使用数据库呢…

MongoDB副本集特点验证

MongoDB副本集特点验证 mogodb副本集概述副本集搭建副本集结构验证结果源码地址 mogodb副本集概述 MongoDB副本集是将数据同步在多个服务器的过程。 复制提供了数据的冗余备份&#xff0c;并在多个服务器上存储数据副本&#xff0c;提高了数据的可用性&#xff0c; 并可以保证…

【MongoDB】索引 - 复合索引

一、准备工作 这里准备一些学生数据 db.students.insertMany([{ _id: 1, name: "张三", age: 20, class: { id: 1, name: "1班" }},{ _id: 2, name: "李四", age: 22, class: { id: 2, name: "2班" }},{ _id: 3, name: "王五…

经验模态分解(Empirical Mode Decomposition,EMD)(附代码)

代码原理 EMD&#xff08;Empirical Mode Decomposition&#xff09;&#xff0c;也称为经验模态分解&#xff0c;是一种将非线性和非平稳信号分解成多个本征模态函数&#xff08;Intrinsic Mode Functions&#xff0c;简称IMF&#xff09;的方法。 EMD的基本原理是通过一系列…