【JVM】从编译后的指令集来再次理解++i和i++的执行顺序

JVM为什么要选用基于栈的指令集架构

  • 与基于寄存器的指令集架构相比,基于栈的指令集架构不依赖于硬件,因此可移植性更好,跨平台性更好
  • 因为栈结构的特性,永远都是先处理栈顶的第一条指令,因此大部分指令都是零地址指令,所以指令集更小
  • 虽然指令集更小,但是同样的一步操作,比基于寄存器所需的指令更多,性能也相对慢

++i的指令集

  • 如下文所示,定义了一段简洁的代码:
public class Demo01 {private void test1(){int i = 10;i = ++i;}
}
  • 根据加号在前就等于“先加加再带入计算”的常识,i的结果必然是11
  • 现在再从指令来看到底是经历了什么样的操作才变成了11:
反编译结果如图所示:

在这里插入图片描述

内容和解释如下:
0 bipush 10   --10压入操作数栈
2 istore_1    --将栈顶数字10存入局部变量表索引为1的位置(索引为0的位置放的是this3 iinc 1 by 1 -- *** 将局部变量表中索引为1的位置的数(也就是10)直接加1 ***
6 iload_1     -- *** 将局部变量表中索引为1的位置的数(现在是11)压入操作数栈 ***
7 istore_1    -- *** 将栈顶数字11存入局部变量表索引为1的位置 ***
8 return      --返回11

同时对比一下i++的指令集

  • 如下文所示,定义了一段简洁的代码:
public class Demo01 {private void test1(){int i = 10;i = i++;}
}
  • 根据加号在后就等于“先带入计算再加加”的常识,i的结果必然是10
  • 现在再从指令来看到底是经历了什么样的操作才变成了10:
反编译结果如图所示:

在这里插入图片描述

内容和解释如下:
0 bipush 10   --10压入操作数栈
2 istore_1    --将栈顶数字10存入局部变量表索引为1的位置(索引为0的位置放的是this3 iload_1     -- *** 将局部变量表中索引为1的位置的数(现在是10)压入操作数栈 ***
4 iinc 1 by 1 -- *** 将局部变量表中索引为1的位置的数(也就是10)直接加1 ***
7 istore_1    -- *** 将栈顶数字10存入局部变量表索引为1的位置 ***
8 return      --返回10

两种情况的不同之处:
  • 最主要的区别就是图片的红框处以及解释中的星号标注处,i++的时候,读入操作数栈的是没有进行加1的值,而++i的时候,读入操作数栈的是加过1的值
  • ++i的时候是先把局部变量表中的10加成了11,然后把11读取到操作数栈,然后再覆盖回局部变量表,所以最后返回了11
  • i++的时候是把10读取到了操作数栈,然后把局部变量表中的10加成了11,但是下一步又用操作数栈的10 覆盖了局部变量表中的11,所以最后返回了10

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

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

相关文章

利用keepalived对zabbix-server做高可用,部署安装keepalived

有2台机器,每台都有1个zabbix-server,然后再每台上再装一个keepalived https://www.keepalived.org/download.html 1,创建安装路径 mkdir /usr/share/keepalived/2,在这个安装路径下面下载keepalived的软件包 我选的版本是1.3…

Redis的事务与关系型数据库事务有何不同?

引言:关于 Redis 的事务很多人可能都是一知半解,大多数人只了解数据库的事务,并且是单体事务,对于 Redis 事务和常见关系型数据库的事务的区别还没有去了解过,本文就来详细进行介绍。 题目 Redis的事务与关系型数据库…

Go微服务: 基于使用场景理解分布式之二阶段提交

概述 二阶段提交(Two-Phase Commit,2PC)是一种分布式事务协议,用于在分布式系统中确保多个参与者的操作具有原子性即所有参与者要么全部提交事务,要么全部回滚事务,以维持数据的一致性它分为两个阶段进行&…

Towards Graph Contrastive Learning: A Survey and Beyond

目录 Towards Graph Contrastive Learning- A Survey and Beyond摘要IntroductionPRELIMINARY符号说明GNN对比学习下游任务 GCL自监督学习增强策略基于规则随机扰动或mask子图采样图扩散 基于学习图结构学习图对抗训练图合理化 对比模式同尺度对比全局上下文局部 跨尺度对比局部…

Polar Web【中等】写shell

Polar Web【中等】写shell Contents Polar Web【中等】写shell思路&探索EXP运行&总结 思路&探索 初看题目,预测需要对站点写入木马,具体操作需要在过程中逐步实现。 打开站点(见下图),出现 file_put_contents 函数,其…

代码解读 | Hybrid Transformers for Music Source Separation[03]

一、背景 接着上一篇代码解读 | Hybrid Transformers for Music Source Separation[02]文章,继续对Hybrid Transformer Demucs 代码进行解读。 解读目标:明确数据从进入算法,在算法内部,以及在算法输出 这三个阶段中 数据的大小是…

pyqt 进度条QProgressBar

pyqt 进度条 QProgressBar效果代码 QProgressBar 在 PyQt 应用程序中,进度条(通常称为 QProgressBar)是一个用于显示任务进度的控件。它可以显示一个水平或垂直的条形图,条形图的长度会随着进度的增加而增加。 QProgressBar 的主…

Java 8 Stream 用法大全

Java 8 Stream 用法大全 目录 Java 8 Stream 用法大全 一、引言 二、Stream 的基础概念 三、创建Stream 四、Stream的操作类型 五、并行Stream与串行Stream 六、性能调优 七、实战案例分析 八、总结与展望 一、引言 Java 8 引入的 Stream API 是处理集合数据的革新之举…

【Python】使用 Python 查询域名的 IP 地址

我们都已经长大 好多梦正在飞 就像童年看到的 红色的蜻蜓 我们都已经长大 好多梦还要飞 就像现在心目中 红色的蜻蜓 🎵 小虎队《红蜻蜓》 在网络开发和运维中,了解域名对应的 IP 地址是一个常见且重要的需求。Python 提供了多种方法…

分布式数据库架构:从单实例到分布式,开发人员需及早掌握?

现在互联网应用已经普及,数据量不断增大。对淘宝、美团、百度等互联网业务来说,传统单实例数据库很难支撑其性能和存储的要求,所以分布式架构得到了很大发展。而开发人员、项目经理,一定要认识到数据库技术正在经历一场较大的变革,及早掌握好分布式架构设计,帮助公司从古…

小米开放式耳机怎么样?倍思、西圣、小米开放式耳机测评比较!

作为一名热衷于分享真实体验的博主,我在过去两年开始接触开放式耳机,并因此受到许多朋友的咨询,询问哪款开放式耳机更加出色。为了找出最佳的开放式耳机,我进行了深入的调查和实地测试。我发现高价并不总是代表高质量,…

refault distance算法的一点理解

这个算法看了好几次了,都没太理解,今天记录一下,加深一下印象。 引用某个博客对这个算法的介绍 一次访问page cache称为fault,第二次访问该页面称为refault。page cache页面第一次被踢出LRU链表并回收(eviction)的时刻称为E&#…

C++基础与深度解析 | 类与面向对象编程 | 数据成员 | 成员函数 | 访问限定符与友元 | 构造、析构成员函数 | 字面值类、成员指针与bind交互

文章目录 一、结构体与对象聚合二、成员函数(方法)三、访问限定符与友元1.访问限定符2.友元(慎用) 四、构造、析构与复制成员函数1.构造函数2.析构函数3.补充 五、字面值类,成员指针与bind交互1.字面值类2.成员指针3.b…

C语言实现三角波生成

C语言实现三角波生成 #include <stdio.h>#define SAMPLE_RATE 10000 // 采样率10kHz=10000Hz 对应100us=0.1ms #define UP_TIME 12.5 //上升时间12.5ms #

golang websocket 数据处理和返回JSON数据示例

golang中websocket数据处理和返回json数据示例&#xff0c; 直接上代码&#xff1a; // author tekintiangmail.com // golang websocket 数据处理和返回JSON数据示例&#xff0c; // 这个函数返回 http.HandlerFunc // 将http请求升级为websocket请求 这个需要依赖第三方包 …

大小堆运用巧解数据流的中位数

​​​​​​​​​​ 一、思路 我们将所有数据平分成两份&#xff0c;前面那一部分用小堆来存&#xff0c;后面的部分用大堆来存&#xff0c;这样我们就能立刻拿到中间位置的值。 如果是奇数个数字&#xff0c;那么我们就将把中间值放在前面的大堆里&#xff0c;所以会有两种…

Windows取证分析 | 如何最大程度提升分析效率

本文由安全研究人员Amr Ashraf发表于Cyber5w的官方博客&#xff0c;研究人员在本文中讨论了如何对可疑设备中的内存映像进行安全调查&#xff0c;并利用了Volatility 3和MemProcFS来最大程度提升Windows取证分析的工作效率。 介绍 内存取证是任何计算机取证分析人员的必备技能…

如何给 MySQL 表和列授予权限?(官方版)

目录 授予表级别权限 授予列级别权限 如何给MySQL表和列授予权限是MySQL数据操作中非常重要的步骤&#xff0c;也是企业级使用MySQL数据库的起步点&#xff0c;以下分别参照官方教程整理的MySQL数据库的权限操作。 以下的语句可以直接使用MySQL的命令行进行操作&#xff08;如何…

3038. 相同分数的最大操作数目 I

题目 给你一个整数数组 nums&#xff0c;如果 nums 至少包含 2 个元素&#xff0c;你可以执行以下操作&#xff1a; 选择 nums 中的前两个元素并将它们删除。一次操作的分数是被删除元素的和。 在确保所有操作分数相同的前提下&#xff0c;请你求出最多能进行多少次操作。 …

排序数组 ---- 分治-归并

题目链接 题目: 分析: 用这道题来回顾一下归并排序的思想找到中间结点, 将数组分成两半, 运用递归的思想, 继续对一半进行分半, 分到最后剩一个元素, 再将左右数组合并, 合并两个有序数组, 是先分解, 再合并的过程在合并两个有序数组时, 需要一个额外的数组来记录, 为了避免每…