【JVM】字节码技术:图解字节码形式下的 方法执行流程

一、源文件

package cn.itcast.jvm.t3.bytecode;

/**
* 演示 字节码指令 和 操作数栈、常量池的关系
*/
public class Demo3_1 {
	public static void main(String[] args) {
		int a = 10;
		int b = Short.MAX_VALUE + 1;
		int c = a + b;
		System.out.println(c);
	}
}

二、反编译的字节码文件

[root@localhost ~]# javap -v Demo3_1.class
Classfile /root/Demo3_1.class
	Last modified Jul 7, 2019; size 665 bytes
	MD5 checksum a2c29a22421e218d4924d31e6990cfc5
	Compiled from "Demo3_1.java"
public class cn.itcast.jvm.t3.bytecode.Demo3_1
	minor version: 0
	major version: 52
	flags: ACC_PUBLIC, ACC_SUPER
Constant pool:
	#1 = Methodref 			#7.#26 			// java/lang/Object."<init>":()V
	#2 = Class 				#27 			// java/lang/Short
	#3 = Integer 32768
	#4 = Fieldref 			#28.#29 		//java/lang/System.out:Ljava/io/PrintStream;
	#5 = Methodref 			#30.#31 		// java/io/PrintStream.println:(I)V
	#6 = Class 				#32 			// cn/itcast/jvm/t3/bytecode/Demo3_1
	#7 = Class 				#33 			// java/lang/Object
	#8 = Utf8 				<init>
	#9 = Utf8 				()V
	#10 = Utf8 				Code
	#11 = Utf8 				LineNumberTable
	#12 = Utf8 				LocalVariableTable
	#13 = Utf8 				this
	#14 = Utf8 				Lcn/itcast/jvm/t3/bytecode/Demo3_1;
	#15 = Utf8 				main
	#16 = Utf8 				([Ljava/lang/String;)V
	#17 = Utf8 				args
	#18 = Utf8 				[Ljava/lang/String;
	#19 = Utf8 				a
	#20 = Utf8 				I
	#21 = Utf8 				b
	#22 = Utf8 				c
	#23 = Utf8 				MethodParameters
	#24 = Utf8 				SourceFile
	#25 = Utf8 				Demo3_1.java
	#26 = NameAndType 		#8:#9 			// "<init>":()V
	#27 = Utf8 				java/lang/Short
	#28 = Class 			#34 			// java/lang/System
	#29 = NameAndType 		#35:#36 		// out:Ljava/io/PrintStream;
	#30 = Class 			#37 			// java/io/PrintStream
	#31 = NameAndType 		#38:#39 		// println:(I)V
	#32 = Utf8 				cn/itcast/jvm/t3/bytecode/Demo3_1
	#33 = Utf8 				java/lang/Object
	#34 = Utf8 				java/lang/System
	#35 = Utf8 				out
	#36 = Utf8 				Ljava/io/PrintStream;
	#37 = Utf8 				java/io/PrintStream
	#38 = Utf8 				println
	#39 = Utf8 				(I)V
{
	public cn.itcast.jvm.t3.bytecode.Demo3_1();
		descriptor: ()V
		flags: ACC_PUBLIC
		Code:
			stack=1, locals=1, args_size=1
				0: aload_0
				1: invokespecial #1 		// Method java/lang/Object."<init>":()V
				4: return
			LineNumberTable:
				line 6: 0
			LocalVariableTable:
				Start 		Length 		Slot 	Name 	Signature
					0 			 5 		   0 	this 	Lcn/itcast/jvm/t3/bytecode/Demo3_1;
	public static void main(java.lang.String[]);
		descriptor: ([Ljava/lang/String;)V
		flags: ACC_PUBLIC, ACC_STATIC
		Code:
			stack=2, locals=4, args_size=1
				0: bipush 10
				2: istore_1
				3: ldc #3 					// int 32768
				5: istore_2
				6: iload_1
				7: iload_2
				8: iadd
				9: istore_3
				10: getstatic #4 			// Field java/lang/System.out:Ljava/io/PrintStream;
				13: iload_3
				14: invokevirtual #5 		// Method java/io/PrintStream.println:(I)V
				17: return
			LineNumberTable:
				line 8: 0
				line 9: 3
				line 10: 6
				line 11: 10
				line 12: 17
			LocalVariableTable:
				Start 		Length 		Slot 	Name 	Signature
					0 			18 		   0 	args 	[Ljava/lang/String;
					3 			15 		   1 	   a 	I
					6 			12 		   2 	   b 	I
					10 			 8 		   3 	   c 	I
		MethodParameters:
			Name 		Flags
			args
}

三、常量池载入运行时常量池

在这里插入图片描述

四、方法字节码载入方法区

在这里插入图片描述

五、为main线程分配栈帧内存

(stack=2,locals=4)

在这里插入图片描述

六、int a=10;

1)bipush 10

将一个 byte 压入操作数栈(其长度会补齐 4 个字节),类似的指令还有:

  • sipush:将一个 short 压入操作数栈(其长度会补齐 4 个字节)
  • ldc:将一个 int 压入操作数栈
  • ldc2_w:将一个 long 压入操作数栈(分两次压入,因为 long 是 8 个字节)
  • 这里小的数字都是和字节码指令存在一起,超过 short 范围的数字存入了常量池

在这里插入图片描述

2)istore_1

将操作数栈顶数据弹出,存入局部变量表的 slot 1

在这里插入图片描述

在这里插入图片描述

七、int b=Short.MAX_VALUE+1;

3)ldc #3

从常量池加载 #3 数据到操作数栈

注意:Short.MAX_VALUE 是 32767,所以 32768 = Short.MAX_VALUE + 1 实际是在编译期间计算 好的

在这里插入图片描述

4)istore_2

在这里插入图片描述

在这里插入图片描述

八、int c=a+b;

5)iload_1

在这里插入图片描述

6)iload_2

在这里插入图片描述

7)iadd

在这里插入图片描述

在这里插入图片描述

8)istore_3

在这里插入图片描述

在这里插入图片描述

九、System.out.println©

9)getstatic #4

在这里插入图片描述

在这里插入图片描述

10)iload_3

在这里插入图片描述

在这里插入图片描述

11)invokevirtual #5

找到常量池 #5

定位到方法区 java/io/PrintStream.println:(I)V 方法

生成新的栈帧(分配 locals、stack等)

传递参数,执行新栈帧中的字节码

在这里插入图片描述

执行完毕,弹出栈帧

清除 main 操作数栈内容

在这里插入图片描述

十、返回

12)return

完成 main 方法调用,弹出 main 栈帧

程序结束

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

愿你满腹经纶

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值