【JVM】字节码技术:手撕 多态执行原理
创始人
2024-02-12 04:50:38

一、源文件

package org.example.classLoading;import java.io.IOException;
/*** 演示多态原理,注意加上下面的 JVM 参数,禁用指针压缩* -XX:-UseCompressedOops -XX:-UseCompressedClassPointers*/
public class PolymorphicTest {public static void test(Animal animal){animal.eat();}public static void main(String[] args) throws IOException {test(new Cat());test(new Dog());System.in.read();}
}abstract class Animal {public abstract void eat();@Overridepublic String toString() {return "我是"+this.getClass().getSimpleName();}
}
class Dog extends Animal{@Overridepublic void eat() {System.out.println("啃骨头");}
}
class Cat extends Animal{@Overridepublic void eat() {System.out.println("吃鱼");}
}

二、运行代码

停在 System.in.read() 方法上,这时运行 jps 获取进程 id:4268

PS F:\software\IDEA\JavaProjects\JvmTest> jps
5956 Launcher
10956
17596 Jps
4268 PolymorphicTest

三、运行HSDB工具

进入 JDK 安装目录,执行

F:\software\Java\jdk1.8.0_333>java -cp ./lib/sa-jdi.jar sun.jvm.hotspot.HSDB

进入图形界面 attach 进程 id

在这里插入图片描述

四、查找某个对象

打开 Tools -> Find Object By Query

输入 select d from org.example.classLoading.Dog d 点击 Execute 执行

在这里插入图片描述

五、查看对象内存结构

点击 0x0000020f086acd98 可以看到对象的内存结构。此对象没有任何属性,因此只有对象头的 16 字节

前 8 字节是 MarkWord,后 8 字节就是对象的 Class指针 。目前看不到 Class对象 的实际地址

在这里插入图片描述

六、查看对象Class的内存地址

方式一:连接前面第五节

可以通过 Windows -> Console 进入命令行模式,执行下面命令查找对象中word的内存地址

mem 0x0000020f086acd98 2

命令中有两个参数。参数 1 是对象地址,参数 2 是查看 2 行(即 16 字节)

结果中第二行 0x0000020f373d4128 即为 Class对象 的内存地址

在这里插入图片描述

方式二

Tools -> Class Browser 输入 Dog 查找,可以得到相同的结果:0x0000020f373d4128

在这里插入图片描述

七、查看类的多态方法表

Alt+R 进入 Inspector 工具,输入刚才的 Class对象 内存地址,看到如下界面

在这里插入图片描述

无论通过哪种方法,都可以找到 Dog Class对象 内存地址。发现 vtable 长度为 6,意思就是 Dog 类有 6 个虚方法(多态相关的。final,static 不会列入)

那么这 6 个方法都是谁呢?从 Class 的起始地址开始算,偏移 0x1b8 就是 vtable 的起始地址,进行计算得到:

0x0000020f373d41281b8 +
--------------------
0x0000020f373d42e0

通过 Windows -> Console 进入命令行模式,执行下面命令。得到了 6 个虚方法的入口地址

mem 0x0000020f373d42e0 6

在这里插入图片描述

八、验证方法地址

通过 Tools -> Class Browser 查看每个类的方法定义,比较可知:

  1. Dog - public void eat() @0x0000020f373d40d0

    在这里插入图片描述

  2. Animal - public java.lang.String toString() @0x0000020f373d36a8

    在这里插入图片描述

  3. Object - protected void finalize() @0x0000020f36fd1b10

  4. Object - public boolean equals(java.lang.Object) @0x0000020f36fd15e8

  5. Object - public native int hashCode() @0x0000020f36fd1540

  6. Object - protected native java.lang.Object clone() @0x0000020f36fd1678

    在这里插入图片描述

九、小结

当执行 invokevirtual 指令时

  1. 先通过栈帧中的对象引用找到对象
  2. 分析对象头,找到对象的 实际Class
  3. Class 结构中有 vtable,它在类加载的链接阶段就已经根据方法的重写规则生成好了
  4. 查vtable表 得到方法的具体地址
  5. 执行方法的字节码

相关内容

热门资讯

北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...
长白山自助游攻略 吉林长白山游... 昨天介绍了西坡的景点详细请看链接:一个人的旅行,据说能看到长白山天池全凭运气,您的运气如何?今日介绍...
世界上最漂亮的人 世界上最漂亮... 此前在某网上,选出了全球265万颜值姣好的女性。从这些数量庞大的女性群体中,人们投票选出了心目中最美...
demo什么意思 demo版本... 618快到了,各位的小金库大概也在准备开闸放水了吧。没有小金库的,也该向老婆撒娇卖萌服个软了,一切只...
猫咪吃了塑料袋怎么办 猫咪误食... 你知道吗?塑料袋放久了会长猫哦!要说猫咪对塑料袋的喜爱程度完完全全可以媲美纸箱家里只要一有塑料袋的响...
埃菲尔铁塔在哪 中国仿建埃菲尔... 2019年4月26日,广西南宁市,街头惊现一座巨型山寨版埃菲尔铁塔,高约20米,白色塔身,造型逼真,...
苗族的传统节日 贵州苗族节日有... 【岜沙苗族芦笙节】岜沙,苗语叫“分送”,距从江县城7.5公里,是世界上最崇拜树木并以树为神的枪手部落...
北京的名胜古迹 北京最著名的景... 北京从元代开始,逐渐走上帝国首都的道路,先是成为大辽朝五大首都之一的南京城,随着金灭辽,金代从海陵王...
应用未安装解决办法 平板应用未... ---IT小技术,每天Get一个小技能!一、前言描述苹果IPad2居然不能安装怎么办?与此IPad不...
脚上的穴位图 脚面经络图对应的... 人体穴位作用图解大全更清晰直观的标注了各个人体穴位的作用,包括头部穴位图、胸部穴位图、背部穴位图、胳...