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

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.rhkb.cn/news/103179.html

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

相关文章

sip网络号角喇叭 sip音柱 POE供电广播音箱 ip网络防水对讲终端 sip网络功放

SV-7042TP网络号角喇叭 一、描述 SV-7042TP是我司的一款SIP网络号角喇叭&#xff0c;具有10/100M以太网接口&#xff0c;内置有一个高品质扬声器&#xff0c;将网络音源通过自带的功放和喇叭输出播放&#xff0c;可达到功率30W。SV-7042TP作为SIP系统的播放终端&#xff0c;可…

OpenEuler 安装mysql

下载安装包 建议直接使用在openEuler官方编译移植过的mysql-5.7.21系列软件包 参考&#xff1a;操作系统迁移实战之在openEuler上部署MySQL数据库 | 数据库迁移方案 | openEuler社区官网 MySQL 5.7.21 移植指南&#xff08;openEuler 20.03 LTS SP1&#xff09; | 数据库移植…

panda3d加载模型复习和python面向对象编程属性学习

运行一个python示例&#xff1b;然后去除一些代码&#xff0c;只剩下加载模型相关&#xff0c;如下&#xff1b; from panda3d.core import loadPrcFileData # Configure the parallax mapping settings (these are just the defaults) loadPrcFileData("", "p…

【Docker】存储卷Volume

Docker Volume概念 什么是存储卷 存储卷就是将宿主机的本地文件系统中存在的某个目录直接与容器内部的文件系统上的某一目录建立绑定关系。这就意味着&#xff0c;当我们在容器中的这个目录下写入数据时&#xff0c;容器会将其内容直接写入到宿主机上与此容器建立了绑定关系的…

Vue 中hash 模式与 history 模式的区别

hash 模式&#xff1a; - 地址中永远带着 # 号&#xff0c;不美观。 - 兼容性比较好。 - 通过手机 app 分享地址时&#xff0c;如果 app 效验严格&#xff0c;该地址会被标记为不合法。 history 模式&#xff1a; - 地址干净&#xff0c;美观。 - 兼容性和 hash 模式相比…

es和数据库同步方案

5.5 课程信息索引同步 5.5.1 技术方案 通过向索引中添加课程信息最终实现了课程的搜索&#xff0c;我们发现课程信息是先保存在关系数据库中&#xff0c;而后再写入索引&#xff0c;这个过程是将关系数据中的数据同步到elasticsearch索引中的过程&#xff0c;可以简单成为索引…

nginx基于端口如何配置虚拟主机

在 Nginx 中配置基于端口的虚拟主机&#xff08;也称为服务器块&#xff09;与配置基于域名的虚拟主机类似&#xff0c;但是你需要指定监听的端口。以下是基于端口的虚拟主机配置示例&#xff1a; 假设我们要配置两个不同的虚拟主机&#xff0c;一个监听 8080 端口&#xff0c…

机器学习---常见的距离公式(欧氏距离、曼哈顿距离、标准化欧式距离、余弦距离、杰卡德距离、马氏距离、切比雪夫距离、闵可夫斯基距离、K-L散度)

1. 欧氏距离 欧几里得度量&#xff08;euclidean metric&#xff09;&#xff08;也称欧氏距离&#xff09;是一个通常采用的距离定义&#xff0c;指在m维空 间中两个点之间的真实距离&#xff0c;或者向量的自然长度&#xff08;即该点到原点的距离&#xff09;。在二维和三维…

分布式锁系列之zookeeper分布式锁和mysql分布式锁

目录 介绍 下载安装 基本指令​编辑 java集成zookeeper 官方提供版 永久节点 临时节点​编辑 永久序列化节点 判断当前节点是否存在 获取当前节点中的数据内容 获取当前节点的子节点 更新节点内容 删除节点 zookeeper实现分布式锁 Mysql实现分布式锁 总结 介绍 ZooK…

在家构建您的迷你 ChatGPT

ChatGPT 玩起来很有趣。您很可能还希望拥有自己的私下运行的副本。实际上,这是不可能的,因为 ChatGPT 不是一个可供下载的软件,并且它需要强大的计算机能力才能运行。但是您可以构建一个可以在商用硬件上运行的精简版本。在这篇文章中,您将了解 什么语言模型可以表现得像 C…

HDLBits-Verilog学习记录 | Verilog Language-Basics(2)

文章目录 9.Declaring wires | wire decl10. 7458 chip 9.Declaring wires | wire decl problem:Implement the following circuit. Create two intermediate wires (named anything you want) to connect the AND and OR gates together. Note that the wire that feeds the …

类加载器与双亲委派

类加载器与双亲委派 Java 类加载器&#xff08;Class Loader&#xff09;是 Java 虚拟机&#xff08;JVM&#xff09;的一部分&#xff0c;负责将类的字节码加载到内存中&#xff0c;并将其转换为可执行的 Java 对象。类加载器在 Java 应用程序中起着重要的作用&#xff0c;它…

【校招VIP】TCP/IP模型之常用协议和端口

考点介绍&#xff1a; 大厂测试校招面试里经常会出现TCP/IP模型的考察&#xff0c;TCP/IP协议是网络基础知识&#xff0c;是互联网的基石&#xff0c;不管你是做开发、运维还是信息安全的&#xff0c;TCP/IP 协议都是你绕不过去的一环&#xff0c;程序员需要像学会看书写字一样…

java.lang.UnsupportedOperationException解决方法

java.lang.UnsupportedOperationException解决方法 先放错误信息业务场景报错分析先看报错代码位置进入源码查看至此 真相大白 解决方法总结 先放错误信息 业务场景 已知有学生 张三李四王五赵六 等人 private List<String> nameList Arrays.asList("张三", &…

Nginx前后端服务器部署

Nginx作为正反向代理的中转站&#xff0c;是连接前后端网络服务的媒介 Nginx下载&#xff1a;http://nginx.org/download/http://nginx.org/download/ 一、上传到服务器固定路径下并解压 上传到/opt/software/nginx-1.19.0.tar.gz cd /opt/software/ tar -zxvf nginx-1.19.0.…

Orchestrator自身高可用性方案

目录 获得 HA 的方法 一 没有高可用性 &#xff08;No high availability&#xff09; 使用场景 架构组成 架构图 二 半高可用性&#xff08;Semi HA&#xff09; 三 基于共享数据库后端高可用&#xff08;HA via shared backend&#xff09; 四 基于Raft协议高可用 五…

【Terraform学习】使用 Terraform 从 EC2 实例访问 S3 存储桶(Terraform-AWS最佳实战学习)

使用 Terraform 从 EC2 实例访问 S3 存储桶 实验步骤 前提条件 安装 Terraform&#xff1a; 地址 下载仓库代码模版 本实验代码位于 task_ec2_s3connet 文件夹中。 变量文件 variables.tf 在上面的代码中&#xff0c;您将声明&#xff0c;aws_access_key&#xff0c;aws_…

shell 11(shell重定向输入输出)

一、标准输入输出 标准输入介绍 从键盘读取用户输入的数据&#xff0c;然后再把数据拿到Shell程序中使用; 标准输出介绍 Shell程序产生的数据&#xff0c;这些数据一般都是呈现到显示器上供用户浏览查看

数字 IC 设计职位经典笔/面试题(三)

共100道经典笔试、面试题目&#xff08;文末可全领&#xff09; 1. IC 设计中同步复位与异步复位的区别&#xff1f; 同步复位在时钟沿变化时&#xff0c;完成复位动作。异步复位不管时钟&#xff0c;只要复位信号满足条件&#xff0c;就完成复位动作。异步复位对复位信号要求…

第1章:计算机网络体系结构

文章目录 1.1 计算机网络 概述1.概念2.组成3.功能4.分类5.性能指标1.2 计算机网络 体系结构&参考模型1.分层结构2.协议、接口、服务3.ISO/OSI模型:七层4.TCP/IP模型:四层1.1 计算机网络 概述 1.概念