JVM——类加载与字节码技术—字节码指令

news2024/10/1 3:24:04

2.字节码指令

2.1 入门

jvm的解释器可以识别平台无关的字节码指令,解释为机器码执行。

 

 

 2a b7  00 01  b1

this .    init() return

 

准备了System.out对象,准备了参数“hello world”,准备了对象的方法println(String)V,并return

2.2 javap 工具

这里常量池直接把查询结果放在了右边。 

有了javap,终于不用看那狗屎字节码文件了 

这部分是方法信息里的init构造方法。

 main方法

有参数类型,访问类型,方法属性,局部变量表,方法参数信息等等

2.3 图解方法执行流程

1)原始 java 代码

b是Short类型的最大值+1。 

2)编译后的字节码文件

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

java代码执行时会由java虚拟机的类加载器将main方法所在类进行类加载。

类加载就是把class文件里的字节数据读取到内存里面。

运行时常量池是方法区的组成部分

 32768对应的是源代码里面的short.value+1,比较小的数字不会存储在常量池,比如10,10会跟着方法的字节码指令存一起,一旦数字范围超过整数最大值就会存储在常量池中。

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

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

绿色区域是局部变量表,蓝色是操作数。字节码指令里面有一个栈的最大深度和局部变量表的长度。这两项决定了栈帧内存大小。

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

bipush 10

istore_1

 然后a被复制为10,对应操作就是a=10

1dc #3

 istore 2

  

iload1

局部变量表中不能执行a+b的操作,所以,执行引擎会对它们进行一个读取。

iload2

iadd

 iadd操作是将操作数栈中的两个数取出来相加再放回去。

istore 3

给c赋值

 

getstatic #4

这个是到常量池中找一个成员变量的引用。这里是找System.out。找到之后不是把对象放入操作数栈,而是获取引用

 

 iload_3

执行打印需要参数c,所以将局部变量表中c的值32778读入到操作数栈

 

 invokevirtual #5

在常量池中找到5号条目,执行println(I)方法,参数 l 表示整数。

 println方法执行时会找到方法区中新的方法,然后分配一个新的栈帧

执行时会把32778作为参数传递给新的栈帧中作为整数参数完成打印操作。

 return

 2.4练习-分析a++

分析

a++执行的指令是iinc,但是这玩意直接原地拉屎变大,不需要进栈又出栈。

a++是iload先,++a是iinc先

iinc的两个参数,一个是要对哪个槽位做自增,一个是自增多少。

 

 

 

 

 

 

 到这里第一个加法结束了。

 

2.5 条件判断指令

 

 较小的数用iconst表示,-1到5的数

ifne 不成立时会跳转到12行,压20入栈然后往下执行。

成立时就直接往下执行然后到goto跳过12,14,直接返回

 

2.6 循环控制指令

 依旧是if+goto

 if_icmpge判断是否大于等于10,是的话就跳到14

do_while

for循环

2.7 练习 - 判断结果

 先load,再iinc,最后istore,又把栈里的load到的数据放回去了。

先把0读进操作数栈的,然后局部变量表上x自增1变成,然后将局部变量表上的0赋值给x.

2.8 构造方法

1) <cinit>()v

静态变量初始化,静态代码块从上到下依次执行

 

cinit是整个类的构造方法。

2) <init>()V

init是实例的构造方法。

从上到下有成员变量,初始化代码块,有参构造。

最后答案是s3 30

2.9方法调用

类中从上到下有构造方法,私有方法,final方法,公共方法,静态方法。

通过对象和类型都调用了静态方法 

有三种指令出现。

invokevirtual是动态绑定,公共方法有可能子类也有可能父类,要在运行时确定。

另外两个都是静态绑定,可以直接找到执行地址。

执行new的时候会先分配内存给它,然后把对象的引用放到操作数栈。

dup是对栈顶的复制,操作数栈里有两个相同的引用。

invokespecial会根据栈顶的引用调用对应的构造方法。 这里消耗一个引用

astore_1会根据剩余的引用出栈存储到局部变量表中。这里消耗一个引用

执行到d.test4()时先把引用放入栈,但由于静态方法不需要引用,所以又pop弹出了,然后用invokestatic执行test4了。

要调用静态方法直接用类名去调用即可,否则会产生多余的虚拟机指令。

2.10 多态的原理

在上面有一个invokevirtual不能直接找到地址去执行,需要找到是父类还是子类。

研究invokevirtual就是研究多态的原理

面试高频题:讲讲什么是多态,底层原理是啥

1) 运行代码

64位操作系统为了节省内存用了指针压缩,查看地址时要换算不方便

 

代码中一个Animal父类,一个抽象方法eat(),一个toString方法,还有两个子类继承了Animal父类。

在公共类中有一个test方法,参数是Animal,这里产生了多态,实际对象可能是cat,也可能是dog. 

2)运行 HSDB 工具

JDK9之后,执行JHSDB HSDB 

 

3)找某个对象

 

 查询语句和sql语句十分相似,这里通过查询类型别名查到dog对象在内存中的地址。

这里虚拟机中只有一个dog对象,所以查到的是唯一dog.

4)查看对象内存结构

5) 查看对象 Class 的内存地址

 第二行是类型指针,用类型指针继续查

 上面是类的结构。

6)查看类的 vtable

接着找类中的方法,多态的方法存在vtable虚方法表中。在类结构的最后。

 是该类的地址加上1B8就是vtable地址。vtable长度是6。

然后看见6个支持重写的方法的入口地址。

7)验证方法地址

在虚方法表中的最后一个方法对应的就是dog类的eat方法。

 因为dog类没有重写父类,用的是Animal的toString方法。

 ​​​​​​​

方法表中的第一项有Object的finalize,clone,equals方法 ,因为Animal和dog都没有重写这些方法。

8) 小结

一句话总结:invokevirtual指令调用的对象vtable中的方法

类加载阶段指的是 验证、准备、解析 这三个阶段,即加载之后,初始化之前、 

2.11 异常处理

try-catch

2 4 是try中的内容, try中如果没有发生异常,就会直接去到12了。

借助Exception table异常表检测[2~5)行内容,不包含5,2~4有异常会先跟声明的异常是否一致或是子类异常,是的话就会进入第8行。

第8行astore_2是把异常对象的引用地址存储下面局部变量的e槽位上,就是catch那一行的执行。

9,11就是i=20.

多个single-catch 块的情况

 

 

与try_catch的相差不多。

multi-catch 的情况

直接一个catch块捕获多个异常。

 

finally

 字节码

因为有可能发生Exception父类的异常,所以异常表里面又多了别的异常类型。 

finally的工作方法就是将finally中的东西放在每一个分支后面,在reutrn前面,以此保证一定会被执行。

因此有三个分支,一个是try,一个是Exception的catch,一个是非Exception的catch.

 2.12 练习 - finally 面试题

finally 出现了 return

 正确答案是20。

 

 简单来说,就是即使报了异常,但是最后还是执行finally例的ireturn,不会执行athrow

抛异常和返回值,这两个是冲突的,只能执行一个,平时绝对不能在finally中return

该代码最后正常执行完没有除零报错。

finally 对返回值影响

 最后返回的是10

2.13 synchronized

new时复制了一份,一个用于调用构造方法,一个是给了局部变量表。

synchronized(lock)先将lock引用加载到操作数栈,然后又复制了一份。

待会一个给monitorenter 指令用,一个给了monitorexit指令用,加锁和解锁。

然后一个lock存入局部变量表2槽,剩下那个给了monitorenter 加锁。

然后12~17是打印指令

20~22是把2号槽位的引用加载到栈顶并给monitorexit解锁,然后goto return正常结束。

 如果12~22有异常会进到25.

25将错误保存到局部变量表。26~27将lock引用给monitorexit解锁。

28,29加载异常类抛出。

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

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

相关文章

车载充电器日本PSE认证申请资料和流程

PSE认证是日本针对电气用品的一个强制性安全认证。 日本的采购商在购进商品后一个月内必须向日本经济产业省&#xff08;METI&#xff09;注册申报。在日本市场上销售的DENAN目录范围内的电气电子产品都必须通过PSE认证。日本DENAN将电气电子产品分为两类&#xff1a;特定电气…

CSS background 背景

background属性为元素添加背景效果。 它是以下属性的简写&#xff0c;按顺序为&#xff1a; background-colorbackground-imagebackground-repeatbackground-attachmentbackground-position 以下所有示例中的花花.jpg图片的大小是4848。 1 background-color background-col…

【面试专题】Spring篇①

&#x1f4c3;个人主页&#xff1a;个人主页 &#x1f525;系列专栏&#xff1a;Java面试专题 目录 1.你知道 Spring 框架中有哪些重要的模块吗&#xff1f; 2. 谈谈你对 IOC 的认识。 3. 谈谈你对 AOP 的认识。 4.在实际写代码时&#xff0c;有没有用到过 AOP&#xff1f;用…

数字化技术无限延伸,VR全景点亮智慧生活

随着互联网的发展&#xff0c;我们无时无刻不再享受着互联网给我们带来的便利&#xff0c;数字化生活正在无限延伸&#xff0c;各行各业也开始积极布局智能生活。要说智慧生活哪个方面应用的比较多&#xff0c;那应该就是VR全景了&#xff0c;目前VR全景已经被各个行业广泛应用…

PyPI 如何在本地配置访问不同的仓库地址

PyPI 是可以在本地计算机上进行配置来访问远程的仓库地址的。 检查配置文件 检查配置文件使用的命令为&#xff1a; pip config -v list 通过上面的配置文件&#xff0c;我们可以知道 Python 的 PyPI 的配置文件信息。 上面图片显示的是配置文件的扫描路径。 修改 pip.ini…

flink checkpoint时exact-one模式和atleastone模式的区别

背景&#xff1a; flink在开启checkpoint的时候有两种模式可以选择&#xff0c;exact-one和atleastone模式&#xff0c;那么这两种模式有什么区别呢&#xff1f; exact-one和atleastone模式的区别 先说结论&#xff1a;exact-one可以完全做到状态的一致性&#xff0c;而atle…

gorm中正确的使用json数据类型

一、说明 1、JSON 数据类型是 MySQL 5.7.8 开始支持的。在此之前&#xff0c;只能通过字符类型&#xff08;CHAR&#xff0c;VARCHAR 或 TEXT &#xff09;来保存 JSON 文档。现实中也很多人不会采用json的存储方式&#xff0c;直接定义一个字符类型,让前端转换传递进来,返回给…

Spring Boot多环境指定yml或者properties

Spring Boot多环境指定yml或者properties 文章目录 Spring Boot多环境指定yml或者properties加载顺序配置指定某个yml 加载顺序 ● application-local.properties ● application.properties ● application-local.yml ● application.yml application.propertes server.port…

2023前端面试笔记 —— CSS3

系列文章目录 内容链接2023前端面试笔记HTML52023前端面试笔记CSS3 文章目录 系列文章目录前言一、CSS选择器的优先级二、通过 CSS 的哪些方式可以实现隐藏页面上的元素三、px、em、rem之间有什么区别&#xff1f;四、让元素水平居中的方法有哪些五、在 CSS 中有哪些定位方式六…

什么是遗传算法(Genetic Algorithm,简称 GA)?

目录 一、遗传算法介绍二、遗传算法应用场景三、遗传算法具体案列1、求解旅行商问题&#xff08;TSP 问题&#xff09;2、求解一个矩阵中的最大值3、基于遗传算法的图像压缩方法 四、遗传算法重要意义五、生物进化与遗传算法之间的关系 一、遗传算法介绍 遗传算法&#xff08;…

Sketch 98 中文版-mac矢量绘图设计

Sketch是一款专为Mac操作系统设计的矢量图形编辑软件&#xff0c;被广泛应用于UI/UX设计、网页设计、移动应用设计等领域。Sketch提供了各种工具和功能&#xff0c;包括绘图、图形设计、排版等&#xff0c;可以帮助设计师轻松地创建高质量的矢量图形和模型。Sketch的主要特点包…

自动气象站丨自动观测和记录气象信息

所谓自动气象站&#xff0c;是指无需人工就能自动检测多种气象要素&#xff0c;并将数据实时发送给观测中心的气设备。它是填补小区域气象探测数据空白的重要手段。自动气象站主要由传感器、数据采集器、太阳能供电系统、立杆组成&#xff0c;可以监测风速、风向、降雨量、空气…

[MyBatis系列①]增删改查

目录 1、基础回顾 2、例子引入 3、映射文件 4、增删改查 4.1、add 4.2、delete 4.3、update 4.4、check 5、核心配置文件 5.1、properties 5.2、typeAliases 5.2.1、自定义 5.2.2、⭐MyBatis自带 5.3、environments 5.3.1、environment 5.3.2、transactionMana…

DataWhale 机器学习夏令营第三期——任务二:可视化分析

DataWhale 机器学习夏令营第三期 学习记录二 (2023.08.23)——可视化分析1.赛题理解2. 数据可视化分析2.1 用户维度特征分布分析2.2 时间特征分布分析 DataWhale 机器学习夏令营第三期 ——用户新增预测挑战赛 学习记录二 (2023.08.23)——可视化分析 2023.08.17 已跑通baseli…

论文解读:Image-Adaptive YOLO for Object Detection in Adverse Weather Conditions

发布时间&#xff1a;2022.4.4 (2021发布&#xff0c;进过多次修订) 论文地址&#xff1a;https://arxiv.org/pdf/2112.08088.pdf 项目地址&#xff1a;https://github.com/wenyyu/Image-Adaptive-YOLO 虽然基于深度学习的目标检测方法在传统数据集上取得了很好的结果&#xf…

【C++数据结构】二叉搜索树

【C数据结构】二叉搜索树 目录 【C数据结构】二叉搜索树二叉搜索树概念二叉搜索树操作二叉搜索树的查找二叉搜索树的插入二叉搜索树的删除二叉搜索树的实现二叉搜索树的应用二叉搜索树的性能分析 作者&#xff1a;爱写代码的刚子 时间&#xff1a;2023.8.22 前言&#xff1a;二…

MySQL数据库管理操作

MySQL常用的数据类型 int&#xff1a;整型 用于定义整数类型的数据float&#xff1a;单精度浮点4字节32位准确表示到小数点后六位double&#xff1a;双精度浮点8字节64位char&#xff1a;固定长度的字符类型用于定义字符类型数据。Char如果存入数据的实际长度比指定长度要…

前端工程化概述

软件工程定义&#xff1a;将工程方法系统化地应用到软件开发中 前端发展历史 前端工程化的发展历史可以追溯到互联网的早期阶段&#xff0c;随着前端技术的不断演进和互联网应用的复杂化&#xff0c;前端工程化也逐渐成为了前端开发的重要领域。以下是前端工程化的主要发展里程…

诚迈科技子公司智达诚远与Unity中国达成合作,打造智能座舱新时代

2023 年 8 月 23 日&#xff0c;全球领先的实时 3D 引擎 Unity 在华合资公司 Unity 中国举办发布会&#xff0c;正式对外发布 Unity 引擎中国版——团结引擎&#xff0c;并带来专为次世代汽车智能座舱打造的团结引擎车机版。发布会上&#xff0c;诚迈科技副总裁、诚迈科技子公司…

C 实现Window/DOS 键盘监听事件

今天是重新复习C语言实现的第一天&#xff0c;今天想编写C 对Windwos/Dos 键盘事件的学习。但是我在安装Visual Studio 2022 没有安装MFC 框架&#xff0c;今天记录下VS追加 MFC框架。 Visual Studio 2022 追加MFC 1、打开vs&#xff0c;点击创建新项目&#xff0c;右侧滑动框…