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

这篇具有很好参考价值的文章主要介绍了JVM——类加载与字节码技术—字节码指令。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

2.字节码指令

2.1 入门

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

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

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

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

 2a b7  00 01  b1

this .    init() return

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

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

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

2.2 javap 工具

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

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

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

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

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

 main方法

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

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

2.3 图解方法执行流程

1)原始 java 代码

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

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

2)编译后的字节码文件

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

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

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

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

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

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

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

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

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

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

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

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

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

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

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

bipush 10
JVM——类加载与字节码技术—字节码指令,JVM,jvm
istore_1

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

 然后a被复制为10,对应操作就是a=10JVM——类加载与字节码技术—字节码指令,JVM,jvm

1dc #3

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

 istore 2

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

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

iload1

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

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

iload2

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

iadd

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

 iadd操作是将操作数栈中的两个数取出来相加再放回去。JVM——类加载与字节码技术—字节码指令,JVM,jvm

istore 3

给c赋值

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

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

getstatic #4

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

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

 iload_3

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

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

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

 invokevirtual #5

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

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

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

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

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

 return

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

 2.4练习-分析a++

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

分析

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

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

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

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

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

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

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

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

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

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

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

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

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

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

2.5 条件判断指令

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

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

JVM——类加载与字节码技术—字节码指令,JVM,jvm 较小的数用iconst表示,-1到5的数

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

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

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

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

2.6 循环控制指令

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

 依旧是if+goto

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

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

do_while

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

for循环

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

2.7 练习 - 判断结果

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

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

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

2.8 构造方法

1) <cinit>()v

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

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

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

cinit是整个类的构造方法。

2) <init>()V

init是实例的构造方法。

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

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

最后答案是s3 30

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

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

2.9方法调用

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

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

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

有三种指令出现。

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

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

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

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

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

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

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

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

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

2.10 多态的原理

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

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

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

1) 运行代码

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

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

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

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

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

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

2)运行 HSDB 工具

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

JDK9之后,执行JHSDB HSDB 

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

3)找某个对象

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

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

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

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

4)查看对象内存结构

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

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

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

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

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

 上面是类的结构。

6)查看类的 vtable

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

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

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

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

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

7)验证方法地址

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

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

JVM——类加载与字节码技术—字节码指令,JVM,jvm 因为dog类没有重写父类,用的是Animal的toString方法。

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

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

8) 小结

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

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

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

2.11 异常处理

try-catch

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

JVM——类加载与字节码技术—字节码指令,JVM,jvm2 4 是try中的内容, try中如果没有发生异常,就会直接去到12了。

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

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

9,11就是i=20.

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

多个single-catch 块的情况

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

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

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

与try_catch的相差不多。

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

multi-catch 的情况

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

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

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

finally

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

 字节码

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

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

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

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

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

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

 2.12 练习 - finally 面试题

finally 出现了 return

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

 正确答案是20。

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

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

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

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

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

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

finally 对返回值影响

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

 最后返回的是10

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

2.13 synchronized

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

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

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

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

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

然后12~17是打印指令

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

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

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

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

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

28,29加载异常类抛出。

JVM——类加载与字节码技术—字节码指令,JVM,jvm文章来源地址https://www.toymoban.com/news/detail-669563.html

到了这里,关于JVM——类加载与字节码技术—字节码指令的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • JVM-透彻理解字节码以及指令

    一、字节码与指令概述 生成字节码: 解释:         cafe babe -  魔数         0000 0031 - 版本号,前面大版本,后面小版本         0022 - 常量池大小 二、JVM编译基本原理 示例: 大白话:         符号解析: int x = 5 -  int 类型的字段 x值为5 以及作用域 大白话:        

    2024年01月22日
    浏览(45)
  • JVM之类加载与字节码

    根据 Java 虚拟机规范,Class 文件通过 ClassFile 定义。ClassFile 的结构如下: 通过分析 ClassFile 的内容,我们便可以知道 class 文件的组成。 下面这张图是通过 IDEA 插件 jclasslib 查看的,你可以更直观看到 Class 文件结构。使用 jclasslib 不光可以直观地查看某个类对应的字节码文件

    2024年02月14日
    浏览(47)
  • JVM之类加载与字节码(一)

    根据 Java 虚拟机规范,Class 文件通过 ClassFile 定义。ClassFile 的结构如下: 通过分析 ClassFile 的内容,我们便可以知道 class 文件的组成。 下面这张图是通过 IDEA 插件 jclasslib 查看的,你可以更直观看到 Class 文件结构。使用 jclasslib 不光可以直观地查看某个类对应的字节码文件

    2024年02月14日
    浏览(46)
  • JVM之类加载与字节码(二)

    类从被加载到虚拟机内存中开始到卸载出内存为止,它的整个生命周期可以简单概括为 7 个阶段::加载(Loading)、验证(Verification)、准备(Preparation)、解析(Resolution)、初始化(Initialization)、使用(Using)和卸载(Unloading)。其中,验证、准备和解析这三个阶段可以

    2024年02月13日
    浏览(98)
  • 一、认识 JVM 规范(JVM 概述、字节码指令集、Class文件解析、ASM)

    JVM : Java Virtual Machine ,也就是 Java 虚拟机 所谓虚拟机是指:通过软件模拟的具有完整硬件系统功能的、运行在一个完全隔离环境中的计算机系统。 即:虚拟机是一个计算机系统。这种计算机系统运行在完全隔离的环境中,且它的硬件系统功能是通过软件模拟出来的。 JVM 通

    2024年01月23日
    浏览(54)
  • p7付费课程笔记:jvm基础知识、字节码、类加载器

    机器语言-编程语言-高级语言(java,c++,Go,Rust等) 面向过程–面向对象-面向函数 java是一种面向对象、静态类型、编译执行,有VM(虚拟机)/GC和运行时、跨平台的高级语言。重点:VM(虚拟机)/GC(Garbage Collector)和运行时、跨平台。 跨平台步骤:字节码文件被虚拟机加载(

    2024年02月10日
    浏览(41)
  • 深入理解JVM虚拟机第二十七篇:详解JVM当中InvokeDynamic字节码指令,Java是动态类型语言么?

     😉😉 学习交流群: ✅✅1:这是孙哥suns给大家的福利! ✨✨ 2:我们免费分享Netty、Dubbo、k8s、Mybatis、Spring...应用和源码级别的视频资料 🥭🥭3:QQ群: 583783824   📚📚  工作微信: BigTreeJava 拉你进微信群,免费领取! 🍎🍎4:本文章内容出自上述:Spring应用课程!💞💞

    2024年02月04日
    浏览(46)
  • 【Java高级应用:深入探索Java编程的强大功能,JVM 类加载机制, JVM 内存模型,垃圾回收机制,JVM 字节码执行,异常处理机制】

    本人详解 作者:王文峰,参加过 CSDN 2020年度博客之星,《Java王大师王天师》 公众号:JAVA开发王大师,专注于天道酬勤的 Java 开发问题 中国国学、传统文化和代码爱好者的程序人生,期待你的关注和支持!本人外号:神秘小峯 山峯 转载说明:务必注明来源(注明:作者:

    2024年01月16日
    浏览(91)
  • Java安全——JVM类加载器(1),啃下这些Framework技术笔记

    先自我介绍一下,小编浙江大学毕业,去过华为、字节跳动等大厂,目前阿里P7 深知大多数程序员,想要提升技能,往往是自己摸索成长,但自己不成体系的自学效果低效又漫长,而且极易碰到天花板技术停滞不前! 因此收集整理了一份《2024年最新网络安全全套学习资料》

    2024年04月29日
    浏览(36)
  • 【JVM001】宋红康JVM字节码举例

    1 Integer 说明: 1 String package jvmT; 说明: 1 Object 执行结果: 说明: (1)成员变量(非静态)赋值过程:①默认初始化—②显示初始化/代码块中初始化—③构造器中初始化—④有了对象之后可以f.x或者f.method()设置属性值 (2)方法有多态,属性没有多态 main方法的字节码文件

    2024年02月06日
    浏览(35)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包