【JVM】字节码技术:手撕 多态执行原理

news2024/9/24 11:30:33

一、源文件

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

    @Override
    public String toString() {
        return "我是"+this.getClass().getSimpleName();
    }
}
class Dog extends Animal{
    @Override
    public void eat() {
        System.out.println("啃骨头");
    }
}
class Cat extends Animal{
    @Override
    public 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 的起始地址,进行计算得到:

0x0000020f373d4128
			   1b8 +
--------------------
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. 执行方法的字节码

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

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

相关文章

【序列召回推荐】(task2)序列召回GRU4Rec和faiss使用

学习总结: 一般的RNN模型我们的输入和输出是什么,我们对RNN输入一个序列 X[x1,x2,...,xn]X [x^1,x^2,...,x^n]X[x1,x2,...,xn] ,注意我们序列中的每一个节点都是一个向量,那么我们的RNN会给我们的输出也是一个序列 Y[y1,y2,...,…

[附源码]SSM计算机毕业设计江苏策腾智能科技公司人事管理系统JAVA

项目运行 环境配置: Jdk1.8 Tomcat7.0 Mysql HBuilderX(Webstorm也行) Eclispe(IntelliJ IDEA,Eclispe,MyEclispe,Sts都支持)。 项目技术: SSM mybatis Maven Vue 等等组成,B/S模式 M…

.net----特性

特性特性的概念和使用特性(Attribute)特性形式特性类参数预定义通用特性类ConditionalAttribute类ObsoleteAttribute类AttributeUsageAttribute类全局特性自定义特性类使用反射访问特性特性的概念和使用 特性(Attribute) 特性类&…

http请求报头header

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 目录 前言 一.认识请求报头(header) 1.Host 2.content-length 3.content-type 常见的三种格式 小结 二.User-Agent(简称UA) 三.Referer 四.C…

进程创建进程终止进程等待

目录前言一、进程创建1.fork()函数(1)fork()函数的基本认识进程调用fork()函数之后,控制权转移到内核中的fork()代码之后,内核做了啥?(2)实验:使用fork()函数创建进程(3&…

跨境电商卖家必知的【圣诞节营销】终极指南(一)

关键词:圣诞节营销、跨境电商卖家 不知不觉又到了年底,而对于跨境电商来说也是非常重要的一段促销时期,也许您已经制定了相关的圣诞节营销大促,但今天我们还是想告诉您一些2022年非常棒的销的创意想法,希望能帮助您提升…

Spring Cloud Alibaba(四)

openFeign配置日志 一、openFeign的日志级别: NONE:不记录日志 (默认). BASIC:只记录请求方法、url、响应状态码和执行时间。 HEADERS:在basic的基础上,增加请求和响应头 FULL:记录请求和响应的头、body…

PyTorch搭建RNN联合嵌入模型(LSTM GRU)实现视觉问答(VQA)实战(超详细 附数据集和源码)

需要源码和数据集请点赞关注收藏后评论区留言私信~~~ 一、视觉问题简介 视觉问答(VQA)是一种同时设计计算机视觉和自然语言处理的学习任务。简单来说,VQA就是对给定的图片进行问答,一个VQA系统以一张图片和一个关于这张图片形式自…

用HTML+CSS+JS写的切水果小游戏它来了

前言 切水果游戏曾经是一款风靡手机的休闲游戏,今天要分享的就是一款网页版的切水果游戏, 由HTMLCSSJS实现,虽然功能和原版的相差太大,但基本的功能具备,效果逼真。感兴趣的小伙伴可收藏学习(完整源码在文…

Heterogeneous Parallel Programming 异构并行编程 - UIUC伊利诺伊大学(持续更新)

Lecture 11.2 Introduction to Heterogeneous异构1.3 Portability and Scalability1.4 Introduction to CUDA 数据并行化 and 执行模型1.5 Introduction to CUDA 内存模型 and 基本函数API1.6 Introduction to CUDA Kernel-based SPMD1.7 更高维的Grid的Kernel-based SPMD例子1…

Linux的基本协议与他的堂兄堂弟

14天学习训练营导师课程: 互联网老辛《 符合学习规律的超详细linux实战快速入门》 努力是为了不平庸~ 学习有些时候是枯燥的,但收获的快乐是加倍的,欢迎记录下你的那些努力时刻(学习知识点/题解/项目实操/遇到的bug/等等&#xf…

教程一 在Go使用JavaScript、HTML和CSS构建Windows、Linux、MacOSX跨平台的桌面应用

Energy是Go语言使用JavaScript、HTML和CSS构建跨平台的桌面应用程序可用于构建跨平台的桌面应用内嵌 Chromium CEF 二进制 环境安装 Energy 命令行工具 使用命令行工具自动安装Energy框架的所有依赖(CEF),支持Window、Linux、MacOSX 安装过程从网络下载CEF和Energy…

二、vue基础入门

一、vue简介 1.1、什么是vue 官方给出的概念:Vue (读音 /vjuː/,类似于 view) 是一套用于构建用户界面的前端框架。 1.2、vue的特性 vue框架的特性,主要体现在如下两方面: 数据驱动视图双向数据绑定 1.2.1、数据驱动视图 在…

高灵敏度艾美捷小鼠肿瘤坏死因子α-ELISpot试剂盒

肿瘤坏死因子-a(TNF-a)由许多不同的细胞类型产生,例如单核细胞,巨噬细胞,T细胞和B细胞。在TNF-a的许多作用中,有针对细菌感染,细胞生长调节,免疫系统调节和参与败血症性休克的保护。…

现代气象仪器 | 太阳辐射测量

南京信息工程大学 实验(实习)报告 实验(实习)名称 现代气象仪器 实验(实习)日期 10.28 得分 指导老师 学院 电信院 专业 电子信息工程 年级 2020 班次 4 姓名 学号 20208327 实验…

万字博客带你全面剖析Spring的依赖注入

1.写在前面 前面的博客我们已经写了Spring的依赖查找,这篇博客我们来了解写Spring的依赖注入。 2.依赖注入的模式和类型 手动模式 - 配置或者编程的方式, 提前安排注入规则 XML 资源配置元信息Java 注解配置元信息API 配置元信息 自动模式 - 实现方…

华为机试 - 最大括号深度

目录 题目描述 输入描述 输出描述 用例 题目解析 算法源码 题目描述 现有一字符串仅由 ‘(‘,’)’,{‘,’}’,[‘,’]’六种括号组成。 若字符串满足以下条件之一,则为无效字符串: ①…

【MySQL】拿来即用 —— MySQL中的数据类型

个人简介:Java领域新星创作者;阿里云技术博主、星级博主、专家博主;正在Java学习的路上摸爬滚打,记录学习的过程~ 个人主页:.29.的博客 学习社区:进去逛一逛~ MySQL数据类型⚪熟悉SQL一、MySQL数据类型总结…

设备树和设备树语法

设备树 驱动代码只负责处理驱动的逻辑,而关于设备的具体信息存放到设备树文件中。许多硬件设备信息可以直 接通过它传递给 Linux,而不需要在内核中堆积大量的冗余代码。 设备树,将这个词分开就是“设备”和“树”,描述设备树的文…

【计算机毕业设计】22.毕业设计选题系统ssm源码

一、系统截图(需要演示视频可以私聊) 引言 近年来,电子商务发展的愈趋成熟使得人们的消费方式以及消费观念发生巨大改变,网上竞拍的拍卖模式随之发展起来。大学拍卖网旨在为湘大学生提供一个线上拍卖的交易平台。平台展示的商品大…