JVM字节码层面分析Java中的i++、++i
Java语言在JVM虚拟机上运行,不可避免的涉及到JVM指令集,下面我们简单分析几个案例。
在进行分析之前,先简单回顾一下JVM的运行时数据区中的JVM虚拟机栈。
一、JVM Stack - JVM虚拟机栈
JVM Stack描述的是:每个方法在执行的同时都会创建一个栈帧,用于存储局部变量表、操作数栈、动态链接、方法出口等信息。每个方法从调用直至完成的过程,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。
默认情况下,一个线程对应一个栈,一个方法对应一个栈帧。
二、示例代码分析
Demo1:
public static void main(String[] args) { int i = 0; i = i++; System.out.println(i); }
输出结果是0。
Demo2:
public static void main(String[] args) { int i = 0; i = ++i; System.out.println(i); }
输出结果是1。
对于初学者,往往会搞不明白为什么会出现这样的结果,下面我们通过JVM指令来分析这两个Demo。
1、Demo1的分析
1.1、Demo1的mian()方法的局部变量表
main() 方法的局部变量表中有两个变量,分别是序号为0的args、序号为1的 i。
1.2、Demo1的main()方法的字节码指令
0、iconst_0 :将常量0压入操作数栈,
1、istore_1 : 弹出操作数栈栈顶元素即常量0,存储到到局部变量表序号为1的位置即变量i中;
至此 int i = 0 操作完成。
2、iload_1: 第1个变量(变量值为0)压入操作数栈
3、iinc 1 by 1:是将局部变量1中的数自增1
4、istrore_1 : 弹出操作数栈栈顶元素即常量0,存储到到局部变量表序号为1的位置即变量i中;
5、getstatic #2 : 获取常量池中#2对应变量的引用
(<java/lang/System.out : Ljava/io/PrintStream;> )压入操作数栈
6、iload_1:第1个变量(变量值为0)压入操作数栈栈顶
7、invokevirtual #3 : 调用常量池中#3对应的常量,即打印的方法( <java/io/PrintStream.println : (I)V>)
· 找到常量池 #3 项;
· 定位到方法区 java/io/PrintStream.println:(I)V 方法
· 生成新的printf() 栈帧(分配 locals、stack等)
· 传递参数i,执行新栈帧中的字节码
· 执行完毕,弹出栈帧
8、return 方法结束
mian() 栈帧出栈
2、Demo2的分析
2.1、Demo2的mian()方法的局部变量表与Demo1一致
2.2、Demo1的main()方法的字节码指令
0、iconst_0 :将常量0压入操作数栈
1、istore_1 : 弹出操作数栈栈顶元素即常量0,存储到到局部变量表序号为1的位置即变量i中;至此 int i = 0 操作完成
2、iinc 1 by 1:是将局部变量 i 中的数自增 1, 此时变量i = 1
3、iload_1: 第1个变量 i (变量值为1)压入操作数栈
4、istore_1 : 弹出操作数栈栈顶元素 1,存储到到局部变量表序号为1的位置即变量 i 中
5、getstatic #2 : 获取常量池中#2 对应变量的引用(<java/lang/System.out : Ljava/io/PrintStream;> )压入操作数栈
6、iload_1 : 第1个变量(变量值为1)压入操作数栈栈顶
7、invokevirtual #3 : 调用常量池中#3对应的常量,即打印的方法( <java/io/PrintStream.println : (I)V>)
8、return 方法结束
三、总结
运行在JVM的业务逻辑,最终都是在JVM运行时数据区,通过JVM指令集,处理一系列变量值操作完成的。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 记一次.NET内存居高不下排查解决与启示
· 探究高空视频全景AR技术的实现原理
· 理解Rust引用及其生命周期标识(上)
· 浏览器原生「磁吸」效果!Anchor Positioning 锚点定位神器解析
· 没有源码,如何修改代码逻辑?
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)