当前位置: 首页 > news >正文

字节码指令

目录

2.1 入门

2.2 javap 工具

2.3 图解方法执行流程

1)原始 java 代码

2)编译后的字节码文件

3)常量池载入运行时常量池

4)方法字节码载入方法区

5)main 线程开始运行,分配栈帧内存

6)执行引擎开始执行字节码

bipush 10

istore_1

ldc #3

istore_2

iload_2

iadd

istore_3

getstatic #4

iload_3

invokevirtual #5

return


2.1 入门

接着上一节,研究一下两组字节码指令,一个是

//构造方法的字节码指令

public cn.itcast.jvm.t5.HelloWorld();

2a b7 00 01 b1

  1. 2a => aload_0 加载 slot 0 的局部变量,即 this,做为下面的 invokespecial 构造方法调用的参数
  2. b7 => invokespecial 预备调用构造方法,哪个方法呢?
  3. 00 01 引用常量池中 #1 项,即【 Method java/lang/Object."":()V 】
  4. b1 表示返回

另一个是 public static void main(java.lang.String[]); 主方法的字节码指令

b2 00 02 12 03 b6 00 04 b1

  1. b2 => getstatic 用来加载静态变量,哪个静态变量呢?
  2. 00 02 引用常量池中 #2 项,即【Field java/lang/System.out:Ljava/io/PrintStream;】
  3. 12 => ldc 加载参数,哪个参数呢?
  4. 03 引用常量池中 #3 项,即 【String hello world】
  5. b6 => invokevirtual 预备调用成员方法,哪个方法呢?
  6. 00 04 引用常量池中 #4 项,即【Method java/io/PrintStream.println:(Ljava/lang/String;)V】
  7. b1 表示返回

请参考

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5

2.2 javap 工具

自己分析类文件结构太麻烦了,Oracle 提供了 javap 工具来反编译 class 文件

[root@localhost ~]# javap -v HelloWorld.class

Classfile /root/HelloWorld.class

Last modified Jul 7, 2019; size 597 bytes

MD5 checksum 361dca1c3f4ae38644a9cd5060ac6dbc

Compiled from "HelloWorld.java"

public class cn.itcast.jvm.t5.HelloWorld

minor version: 0

major version: 52

flags: ACC_PUBLIC, ACC_SUPER

Constant pool:

#1 = Methodref #6.#21 // java/lang/Object."<init>":()V

#2 = Fieldref #22.#23 //

java/lang/System.out:Ljava/io/PrintStream;

#3 = String #24 // hello world

#4 = Methodref #25.#26 // java/io/PrintStream.println:

(Ljava/lang/String;)V

#5 = Class #27 // cn/itcast/jvm/t5/HelloWorld

#6 = Class #28 // java/lang/Object

#7 = Utf8 <init>

#8 = Utf8 ()V

#9 = Utf8 Code

#10 = Utf8 LineNumberTable

#11 = Utf8 LocalVariableTable

#12 = Utf8 this

#13 = Utf8 Lcn/itcast/jvm/t5/HelloWorld;

#14 = Utf8 main

#15 = Utf8 ([Ljava/lang/String;)V

#16 = Utf8 args

#17 = Utf8 [Ljava/lang/String;

#18 = Utf8 MethodParameters

#19 = Utf8 SourceFile

#20 = Utf8 HelloWorld.java

#21 = NameAndType #7:#8 // "<init>":()V

#22 = Class #29 // java/lang/System

#23 = NameAndType #30:#31 // out:Ljava/io/PrintStream;

#24 = Utf8 hello world

#25 = Class #32 // java/io/PrintStream

#26 = NameAndType #33:#34 // println:(Ljava/lang/String;)V

#27 = Utf8 cn/itcast/jvm/t5/HelloWorld

#28 = Utf8 java/lang/Object

#29 = Utf8 java/lang/System

#30 = Utf8 out

#31 = Utf8 Ljava/io/PrintStream;

#32 = Utf8 java/io/PrintStream

#33 = Utf8 println

#34 = Utf8 (Ljava/lang/String;)V

{

public cn.itcast.jvm.t5.HelloWorld();

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 4: 0

LocalVariableTable:

Start Length Slot Name Signature

0 5 0 this Lcn/itcast/jvm/t5/HelloWorld;

public static void main(java.lang.String[]);

descriptor: ([Ljava/lang/String;)V

flags: ACC_PUBLIC, ACC_STATIC

Code:

stack=2, locals=1, args_size=1

0: getstatic #2 // Field

java/lang/System.out:Ljava/io/PrintStream;

3: ldc #3 // String hello world

5: invokevirtual #4 // Method

java/io/PrintStream.println:(Ljava/lang/String;)V

8: return

LineNumberTable:

line 6: 0

line 7: 8

LocalVariableTable:

Start Length Slot Name Signature

0 9 0 args [Ljava/lang/String;

MethodParameters:

Name Flags

args

}

2.3 图解方法执行流程

1)原始 java 代码

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);}
}

2)编译后的字节码文件

[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

}

3)常量池载入运行时常量池

4)方法字节码载入方法区

5)main 线程开始运行,分配栈帧内存

(stack=2,locals=4)

6)执行引擎开始执行字节码

bipush 10

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

sipush 将一个 short 压入操作数栈(其长度会补齐 4 个字节)

ldc 将一个 int 压入操作数栈

ldc2_w 将一个 long 压入操作数栈(分两次压入,因为 long 是 8 个字节)

这里小的数字都是和字节码指令存在一起,超过 short 范围的数字存入了常量池

istore_1

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

ldc #3

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

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

好的

istore_2

iload_1

iload_2

iadd

istore_3

getstatic #4

iload_3

invokevirtual #5

找到常量池 #5 项

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

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

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

执行完毕,弹出栈帧

清除 main 操作数栈内容

return

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

程序结束

相关文章:

字节码指令

目录 2.1 入门 2.2 javap 工具 2.3 图解方法执行流程 1&#xff09;原始 java 代码 2&#xff09;编译后的字节码文件 3&#xff09;常量池载入运行时常量池 4&#xff09;方法字节码载入方法区 5&#xff09;main 线程开始运行&#xff0c;分配栈帧内存 6&#xff09;…...

TLS/SSL证书彻底扫盲

证书格式 pem Privacy Enhanced Mail文本格式&#xff0c;以 -----BEGIN CERTIFICATE----- 开头&#xff0c;以-----END CERTIFICATE-----结尾 der 二进制格式&#xff0c;只保存证书&#xff0c;不保存私钥java和window服务器常见 pfx/p12 Predecessor of PKCS#12二进制格式&…...

WGCNA | 值得你深入学习的生信分析方法!~(网状分析-第五步-高级可视化)

1写在前面 前面我们用WGCNA分析完成了一系列的分析&#xff0c;聚类分割模块。&#x1f970; 随后进一步筛选&#xff0c;找到与我们感兴趣的表型或者临床特征相关的模块&#xff0c;而且进行了模块内部分析。&#x1f618; 再然后是对感兴趣模块进行功能注释&#xff0c;了解模…...

try catch finally执行顺序

try catch finally&#xff0c;try里有return&#xff0c;finally还执行么&#xff1f;答案&#xff1a; 执行&#xff0c;并且返回return时&#xff0c;finally的执行早于try。try-catch-finally的执行顺序无return当try中的t()没有抛出异常public static void main(String[] …...

2023年数学建模美赛D题(Prioritizing the UN Sustainability Goals)分析与编程

2023年数学建模美赛D题分析建模与编程 重要说明&#xff1a; 本文介绍2023年美赛题目&#xff0c;并进行简单分析&#xff1b;本文首先对 D题进行深入分析&#xff0c;其它题目分析详见专题讨论&#xff1b;本文及专题分析将在 2月17日每3小时更新一次&#xff0c;完全免费&am…...

35岁测试工程师被辞退,给你们一个忠告

一&#xff1a;前言&#xff1a;人生的十字路口静坐反思 入软件测试这一行至今已经10年多&#xff0c;承蒙领导们的照顾与重用&#xff0c;同事的支持与信任&#xff0c;我的职业发展算是相对较好&#xff0c;从入行到各类测试技术岗位&#xff0c;再到测试总监&#xff0c;再转…...

华为OD机试题 - 租车骑绿岛(JavaScript)

最近更新的博客 2023新华为OD机试题 - 斗地主(JavaScript)2023新华为OD机试题 - 箱子之形摆放(JavaScript)2023新华为OD机试题 - 考古学家(JavaScript)2023新华为OD机试题 - 相同数字的积木游戏 1(JavaScript)2023新华为OD机试题 - 最多等和不相交连续子序列(JavaScri…...

Linux下Python脚本的编写解析fio(minimal格式)(三)

在服务器测试(storage)过程中&#xff0c;会看到很多人写跑fio的脚本用minimal格式来解析&#xff0c;因为这种格式返回的结果对与脚本(shell,python)解析log非常方便.下面介绍一下这种方式下,用Python来解析log 1 一般客户会要求结果中出现一下参数的值&#xff1a; bandwidth…...

【实战场景二】如何设计一个分布式锁?

如何优雅的设计一个分布式锁&#xff1f;如何设计一个分布式锁&#xff1f;1、什么是分布式锁2、那么分布式锁&#xff0c;具备什么条件呢&#xff1f;3、设计分布式锁有哪些方式&#xff1f;3.1 利用redis实现分布式锁原理3.2 基于数据库做分布式锁3.3 基于zookeeper实现分布式…...

Java中ThreadLocal类详解

ThreadLocal从名字上我们看出&#xff0c;它叫做本地线程变量&#xff0c;每个线程都有各自的的变量&#xff0c;而不再是我们之前的两个线程共用同一个变量&#xff1b;以这个类创建的变量&#xff0c;在多个线程都用到这个变量时&#xff0c;可以为每一个线程创建一个变量副本…...

从一致性角度考虑推荐冷启动长尾推荐问题(一)

前言&#xff1a;目前中长尾推荐的方法有很多&#xff0c;主流的方法有几类比如:1)在没有项目ID嵌入的情况下提高推荐模型的鲁棒性&#xff0c;2)利用有限的交互数据提高学习效率&#xff0c;如使用元学习方法;3)利用物品侧面信息&#xff0c;便于物品ID嵌入的初始化&#xff0…...

电脑(Windows)常用快捷键

简述&#xff1a;实用的键盘快捷键是一个程序员的必备技能&#xff0c;下面给大家整理了一下常用的键盘快捷键&#xff1b; ⭐CtrlP 打开“打印机”对话框&#xff1b; ⭐CtrlW 关闭当前网页&#xff1b; ⭐CtrlF 查找&#xff08;网页内查找&#xff09;&#xff1b; ⭐…...

Java类加载器

1 类加载器 1.1 类加载 当程序要使用某个类时&#xff0c;如果该类还未被加载到内存中&#xff0c;则系统会通过类的加载&#xff0c;类的连接,类的初始化这三个步骤来对类进行初始化。如果不出现意外情况&#xff0c;JVM将会连续完成这三个步骤,所以有时也把这三个步骤统称为…...

信号完整性设计规则之单根信号失真最小化

本文内容从《信号完整性与电源完整性分析》整理而来&#xff0c;加入了自己的理解&#xff0c;如有错误&#xff0c;欢迎批评指正。 1. 通常采用所能容许的最长上升边。 上升边越短&#xff0c;带宽越大&#xff0c;信号完整性问题越严重。 2. 使用可控阻抗走线。 可控阻抗…...

Python3 数据结构

列表 Python中列表是可变的&#xff0c;这是它区别于字符串和元组的最重要的特点&#xff0c;一句话概括即&#xff1a;列表可以修改&#xff0c;而字符串和元组不能。 以下是 Python 中列表的方法&#xff1a; 方法 描述 list.append(x) 把一个元素添加到列表的结尾&#xf…...

Compose-Navigation带参传递

带参传递 目前 compose 还不支持传入对象作为参数&#xff01; 简单双参数 根目录下新建文件夹 entity&#xff0c;新建单例类 ContentType 作为数据类存储位置 新增数据类 DemoContent&#xff0c;这表示我们需要传入的两个参数&#xff0c;后面带问号判空 object ContentT…...

【函数栈帧的创建和销毁】 -- 神仙级别底层原理,你学会了吗?

文章目录1.函数的调用方式 2.函数在栈区上的动作 1.函数的调用方式 相信你对调用函数一点都不陌生&#xff0c;但是在调用函数的过程中&#xff0c;却存在着很多你无法见到的东西&#xff0c;这是底层信息&#xff0c;想要理解透彻&#xff0c;就得深入底层去观察。 本文以…...

Promise的使用及原理

此文章主要讲解核心思想和基本用法&#xff0c;想要了解更多细节全面的使用方式&#xff0c;请阅读官方API 这篇文章假定你具备最基本的异步编程知识&#xff0c;例如知道什么是回调&#xff0c;知道什么是链式调用&#xff0c;同时具备最基本的单词量&#xff0c;例如page、us…...

怎么拥有一个帅气的 CMD 命令窗口 ❓ - Windows

自从拥有这样一个炫酷的命令窗口&#xff0c;我都舍不得关掉它了 关于我为什么我要闲的去 “打扮” 一个命令窗口&#xff0c;这要从星期五下午的一场 摸鱼 &#x1f420; 开始&#xff0c;当时我要创建一个 vue ts vite 的项目练练手&#xff0c;为新项目开始做准备&#x…...

时隔多年再学习Vuex,什么?原来如此简单!

时隔多年再学习Vuex&#xff0c;什么&#xff1f;原来如此简单! start 写 Vue 写了好多年了&#xff0c;少不了和 Vuex 打交道。虽然使用它的次数非常频繁&#xff0c;但是潜意识里总觉得这东西很难&#xff0c;导致遇到与之相关的问题就容易慌张。时至今日&#xff0c;升级版…...

Cadence AMS Designer 保姆级教程:手把手教你搞定数模混合仿真(含Verilog模块导入避坑指南)

Cadence AMS Designer 保姆级教程&#xff1a;手把手教你搞定数模混合仿真&#xff08;含Verilog模块导入避坑指南&#xff09; 数模混合仿真一直是芯片设计中的关键环节&#xff0c;尤其对于刚接触Cadence环境的新手工程师或在校学生来说&#xff0c;从零开始搭建混合仿真环境…...

Linux I2C设备驱动避坑指南:以MPU6050为例,解决i2c_transfer返回EIO错误

Linux I2C设备驱动深度排障&#xff1a;MPU6050的EIO错误全解析 调试嵌入式设备时&#xff0c;最令人沮丧的莫过于那些间歇性出现的错误。它们像幽灵一样时隐时现&#xff0c;让开发者陷入无尽的猜测和试错循环。MPU6050作为一款广泛使用的运动传感器&#xff0c;其I2C接口的稳…...

从 `raster` 到 `terra`:R语言中的栅格数据处理

在R语言中,处理空间数据的包非常多,其中 raster 包曾经是处理栅格数据的首选。然而,随着时间的推移,terra 包逐渐成为了更高效、功能更全面的替代品。今天我们来探讨一下如何从 raster 迁移到 terra,并通过一个实例来展示其使用方法。 为什么选择 terra? terra 包由 ra…...

用Logisim搞定Educoder实训:从数码管驱动到完整交通灯系统的保姆级通关攻略

Logisim实战&#xff1a;从数码管驱动到交通灯系统的Educoder通关全解析 第一次打开Educoder平台的《交通灯系统设计》实训项目时&#xff0c;我和大多数同学一样&#xff0c;面对十二个关卡的层层递进有些手足无措。经过三个通宵的调试和无数次的电路重构&#xff0c;终于摸索…...

PyTorch模型保存加载避坑指南:从state_dict到checkpoint,这5种场景你都会了吗?

PyTorch模型保存加载避坑指南&#xff1a;从state_dict到checkpoint&#xff0c;这5种场景你都会了吗&#xff1f; 在深度学习项目的实际开发中&#xff0c;模型保存与加载看似简单&#xff0c;却隐藏着无数"坑点"。我曾见过团队因一个错误的map_location参数导致生…...

从‘水管’到‘高速公路’:用‘时延带宽积’重新理解你的网络容量,别再让高带宽‘空转’了

从‘水管’到‘高速公路’&#xff1a;用‘时延带宽积’重新理解你的网络容量 想象一下&#xff0c;你正驾驶一辆满载数据的卡车行驶在数字高速公路上。这条路的车道数&#xff08;带宽&#xff09;让你欣喜若狂&#xff0c;但开了半天却发现路上几乎没几辆车——这就是许多工程…...

3步掌握清华PPT模板:终极方案解决学术演示设计难题

3步掌握清华PPT模板&#xff1a;终极方案解决学术演示设计难题 【免费下载链接】THU-PPT-Theme 清华主题PPT模板 项目地址: https://gitcode.com/gh_mirrors/th/THU-PPT-Theme 还在为学术汇报PPT设计而苦恼吗&#xff1f;每次准备答辩、会议或教学演示&#xff0c;你都要…...

智能网联时代的分心驾驶:技术悖论、工程困境与系统化安全框架

1. 项目概述&#xff1a;一个被忽视的致命悖论 作为一名在汽车电子和智能网联领域摸爬滚打了十几年的工程师&#xff0c;我见过太多关于“未来出行”的炫酷概念和激动人心的技术路线图。从早期的车载信息娱乐系统&#xff0c;到后来的高级驾驶辅助系统&#xff0c;再到如今如火…...

告别手动抢购!i茅台自动预约系统的完整指南

告别手动抢购&#xff01;i茅台自动预约系统的完整指南 【免费下载链接】campus-imaotai i茅台app自动预约&#xff0c;每日自动预约&#xff0c;支持docker一键部署&#xff08;本项目不提供成品&#xff0c;使用的是已淘汰的算法&#xff09; 项目地址: https://gitcode.co…...

【信息科学与工程学】【人工智能】【数字孪生】【游戏科学】主要数学模型-第九篇 计算神经科学

认知神经科学的几何、拓扑与计算建模框架 这是一个深度交叉领域的问题,我将从几何表示、拓扑结构、动力学模型和仿真算法四个维度,系统梳理从神经元到全脑的计算神经科学建模方法。 一、神经元与连接的几何表示模型 神经元形态的表示: a) 线表示:将神经元的树突和轴突表示…...