当前位置: 首页 > news >正文

运行时栈帧结构与方法调用

 1 运行时栈帧结构

Java虚拟机以方法作为最基本执行单元,“栈帧”则是用于支持虚拟机进行方法调用和方法执行背后的数据结构。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。

1.1 局部变量表

局部变量表的容量以变量槽为最小单位。

Java虚拟机通过索引定位的方式使用局部变量表。如果访问的是64位数据类型的变量,则说明会同时使用第N和第N+1两个变量槽。虚拟机不允许采用任何方式单独访问其中的某一个。

reference类型表示对一个对象实例的引用,《Java虚拟机规范》既没有说明它的长度,也没明确指出这种引用的结构。但是一般来说,引用类型至少有两项作用:

1)从根据引用直接或间接地查找到对象在Java堆中的数据存放的起始地址或索引。

2)根据引用直接或间接地查找到对象所属数据类型在方法区的存储的类型信息。

1.1.1 实参到形参的传递

当一个方法被调用时,Java虚拟机会使用局部变量表来完成参数值到参数变量列表的传递。如果执行的是实例方法,那局部变量表中第0位索引的变量槽默认是用于传递方法所属对象实例的引用。其余参赛按照参赛表顺序排列。

1.1.2 变量槽重用

局部变量表中的变量槽是可以重用的,方法体中定义的变量,其作用域并不一定会覆盖整个方法体,如果当前字节码PC计数器的值已经超出了某个变量的作用域,那这个变量对应的变量槽就可以交给其他变量来重用。

1.2 操作数栈

操作数栈中元素的数据类型必须与字节码指令的序列严格匹配。

在大多虚拟机的实现里,会进行一些优化处理,令两个栈帧出现一部分重叠。

图 操作数栈重叠实例代码

两个栈帧一部分重叠主要体现在方法中有参数传递的情况。

图 操作数栈重叠代码帧栈重叠部份图示

这样做不仅节约了一些空间,更重要的是在进行方法调用时就可以直接共用一部分数据,无须进行额外的参数复制传递了。

2方法调用

方法调用并不等同于方法中的代码被执行,方法调用阶段唯一的任务就是确定被调用方法的版本(即调用哪一个方法)。程序运行时,进行方法调用是最普遍、最繁琐的操作之一。

2.1 解析

在类加载的解析阶段,会将方法中的一部分符号引用转化为直接引用,这种解析能够成立的前提是:方法在程序真正运行之前就有一个可确定的调用版本,并且这个方法的调用版本在运行期不可改变。

符合“编译器可知,运行期不可变”这个要求的方法,主要有静态方法和私有方法这两大类。

invokestatic

调用静态方法

invokespecial

调用实例构造器<init>()方法、私有方法和父类中的方法

invokevirtual

调用所有的虚方法

invokeinterface

调用接口方法,会在运行时再确定一个实现该接口的对象

invokedynamic

先在运行时动态解析出调用点限定符所引用的方法,然后再执行该方法。前面4条分派逻辑都固化在Java虚拟机内部,而这条指令分派逻辑是由用户设定的引导方法来决定的。

表 Java虚拟机支持的方法调用字节码指令

2.1.1 非虚方法和虚方法

只要能被invokestatic和invokespecial指令调用的方法及被final修饰的方法(尽管它使用invokevirtual指令调用),都可以在解析阶段中确定唯一的调用版本。这些方法被称为“非虚方法”。与之相反的其他方法被称为“虚方法”。

图 方法静态解析演示

2.2 分派

2.1.1 静态分派

静态分派是编译器方法重载的过程。

静态类型(也叫外观类型)在编译器是可知的。而实际类型(也叫运行时类型)要等到运行期才可知。

如:Human man = new Man(); 静态类型为Human,实际类型为Man。

方法重载哪个版本,完全取决于传入参数的数量和数据类型,但虚拟机在重载时是通过参数的静态类型作为判定依据的。

2.1.2 动态分派

动态分派和重写有着很密切的关联。

public class DynamicAllocation {private static class Human {void sayHello() {System.out.println("Hello Human");}}private static class Man extends Human {@Overridevoid sayHello() {System.out.println("Hello Man");}}public static void main(String[] args) {Human human = new Man();human.sayHello();}
}
/*
运行结果:
Hello Man*/

图 上述代码的部份字节码

标红处为main方法中执行sayHello方法的地方。根据《Java虚拟机规范》,invokevirtual指令的运行时解析过程大致分为以下步骤:

  1. 找到操作数栈顶顶第一个元素所指的对象的实际类型,记作C。
  2. 如果在类型C中找到与常量中的描述符和简单名称都相符的方法,则进行校验,如果通过则返回这个方法的直接引用,查找过程结束;不通过则返回java.lang.IllegalAccessError异常。
  3. 否则,按照继承关系从下往上依次对C的各个父类进行第二步的搜索和验证过程。
  4. 如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常。

指令的第一步就是在运行期确定接收者的实际类型,这个过程是Java语言中方法重写的本质。

字段不可能是虚的。

2.1.3 单分派与多分派

方法的接收者与方法的参数统称为方法的宗量。根据分派基于多少种宗量,将分派划分为单分派和多分派两种。

至今的Java语言是一门静态(和接收者及方法的参数都有关,重载)多分派、动态单分派(只和接收者有关)的语言。

2.1.4 虚拟机动态分派的实现

使用虚方法索引来代替元数据查找以提高性能。虚方法表存放着各个方法的实际入口地址。如果某个方法在子类中没有被重写,那子类的虚方法表中的地址入口和父类相同方法的地址入口是一样的。如果重写了这个方法,子类虚方法表中的地址也会被替换为指向子类实现版本的入口地址。

为了程序实现方便,具有相同签名的方法,在父类、子类的虚方法表中都应当具有一样的索引号,这样当类型变换时,仅需变更查找的虚方法表。

虚方法表一般在类加载的连接阶段进行初始化,准备了类的变量初始值后,虚拟机会把该类的虚方法表也一同初始化完毕。

相关文章:

运行时栈帧结构与方法调用

1 运行时栈帧结构 Java虚拟机以方法作为最基本执行单元&#xff0c;“栈帧”则是用于支持虚拟机进行方法调用和方法执行背后的数据结构。栈帧存储了方法的局部变量表、操作数栈、动态连接和方法返回地址等信息。 1.1 局部变量表 局部变量表的容量以变量槽为最小单位。 Java…...

VSCode +gdb+gdbserver远程调试arm开发板

一、下载编译器 从ARM官网下载gcc-arm编译器&#xff0c;编译器中自带gdb和gdbserver&#xff0c;可以省去自己编译。 注&#xff1a;gdb是电脑端程序&#xff0c;gdbserver是arm开发板程序 arm官网链接&#xff1a;https://developer.arm.com/downloads/-/arm-gnu-toolchain-d…...

阿里云大学考试python中级题目及解析-python高级

阿里云大学考试python高级题目及解析 1.以上代码输出结果为 a [1,2,3,None,(),[],] print(len(a))A.4 B.5 C.6 D.syntax error C 列表中元素可以存储任意数据类型 2.将字符串s 中的字母a替换为字母&#xff0c;以下代码正确的是 A.s.swap(“b”&#xff0c;“a”) B.s.r…...

基于FPGA的车牌识别

基于FPGA进行车牌识别 基于FPGA进行车牌识别 1. 文件说明2. 程序移植说明3. 小小的编程感想 本项目的原理讲解视频已经上传到B站“基于FPGA进行车牌识别”。 本项目全部开源&#xff0c;见我本人的Github仓库“License-Plate-Recognition-FPGA”。 1. 文件说明 小技巧&…...

Qt - 进程/线程 补充进阶

Qt - 进程/线程 补充进阶 多线程quit / eixt / terminate QThread例子tdicethread 类.h.cpp widget 类.h.cpp 线程同步 多线程 quit / eixt / terminate quit 应用程序或线程安全的取消事件处理队列的执行&#xff0c;并随后使线程退出&#xff08;如果只希望结束线程并保证它…...

spring笔记

spring 和 springboot的区别 自动配置原理 beanFactory接口和ApplicationContext接口 两个都是 IOC 容器 ApplicationContext接口是BeanFactory接口实现类的子类 功能&#xff1a; ApplicationContext扩展BeanFactory BeanFactoryApplicationContext控制反转国际化支持 …...

最大熵模型

最大熵模型&#xff08;maximum entropy model&#xff09;由最大熵原理推导实现 最大熵原理 最大熵原理是概率模型学习的一个准则。最大熵原理认为&#xff0c;学习概率模型时&#xff0c;在所有可能的概率模型&#xff08;分布&#xff09;中&#xff0c;熵最大的模型时最好…...

微服务中网关的配置

一、添加 Spring Cloud Gateway 依赖 <dependency><groupId>org.springframework.cloud</groupId><artifactId>spring-cloud-starter-gateway</artifactId> </dependency>二、配置网关路由 在application.yaml中配置如下内容&#xff1a…...

Linux基本指令实现4及热键指令详解

目录 Linux热键补充&#xff1a; 1.bc指令&#xff1a; Tab键的智能补充&#xff1a; ctrlc键&#xff1a; uname指令&#xff1a; lscpu指令&#xff1a; lsmem指令&#xff1a; df -h指令&#xff1a; 关机指令&#xff1a; 扩展指令&#xff1a; Linux热键补充&#…...

系统调用与API

系统调用介绍 什么是系统调用 为了让应用程序有能力访问系统资源&#xff0c;也为了让程序借助操作系统做一些由操作系统支持的行为&#xff0c;每个操作系统都会提供一套接口&#xff0c;以供应用程序使用。系统调用涵盖的功能很广&#xff0c;有程序运行所必需的支持&#xf…...

OpenPCDet系列 | 5.4.1 DenseHead中的AnchorGenerator锚框生成模块

文章目录 AnchorGenerator模块AnchorGenerator.generate_anchors函数 AnchorGenerator模块 首先&#xff0c;根据点云场景将其划分为一个个grid&#xff0c;这个grid size是可以通过配置文件设定的点云场景方位和voxel大小计算出来的。 POINT_CLOUD_RANGE: [0, -39.68, -3, 6…...

【开发者指南】如何在MyEclipse中使用HTML或JSP设计器?(上)

MyEclipse v2022.1.0正式版下载 一、HTML & JSP 可视化设计器 本文简要介绍了 MyEclipse HTML 和 JSP Web 设计器的概念、功能和基本操作过程。这两个设计器具有相似的功能和相同的操作模型&#xff0c;但本文为专门针对其类型的内容。本文档中的示例是使用 MyEclipse HT…...

Node开发Web后台服务

简介 Node.js 是一个基于Google Chrome V8 引擎的 JavaScript 运行环境。Node.js 使用了一个事件驱动、非阻塞式 I/O 的模型&#xff0c;使其轻量又高效。Node.js 的包管理器 npm&#xff0c;是全球最大的开源库生态系统。 能方便地搭建响应速度快、易于扩展的网络应用&#…...

Linux下对mmap封装使用

Linux下对mmap封装使用 1、mmap简介2、Linux下mmap使用介绍2.1、mmap函数2.2、munmap函数 3、对mmap进行封装4、对封装类MEM_MAP进行测试5、mmap原理6、源代码下载 1、mmap简介 mmap即memory map&#xff0c;是一种内存映射文件的技术。mmap可以将一个文件或者其它对象映射到进…...

深入了解云计算:发展历程、服务与部署模型、未来趋势与挑战

开篇博主 bluetata 的观点&#xff1a;PaaS 服务必将是未来10年云计算权重最高的趋势&#xff08;05/02/2023 15:32&#xff09; 文章目录 一、前言二、认识了解云计算2.1 什么是云计算2.1.1 维基百科上的云计算定义2.1.2 NIST 标准云计算定义2.1.3 如果被面试如何解释云计算 2…...

使用乐鑫 Web IDE 助力物联网开发

乐鑫 Web IDE 是基于 Eclipse Theia 的框架&#xff0c;支持 ESP-IDF VS Code 插件同时具备多项辅助工具。您可以观看我们在 Espressif DevCon22 上的演示视频​​​​​​​&#xff0c;了解它的实际应用。 【乐鑫开发者大会-21】搭载 ESP-IDF Visual Studio Code 插件的乐鑫 …...

Maven(5)---Maven的部署和发布

Maven的部署和发布 在前面的博客中&#xff0c;我们已经学习了Maven的基础知识、依赖管理、插件和生命周期&#xff0c;以及多模块项目管理。本篇博客将介绍Maven的部署和发布功能。 什么是部署和发布 在软件开发过程中&#xff0c;部署和发布是非常重要的环节。部署是指将软…...

内网渗透之权限维持-黄金白银票据隐藏账户远控-RustDeskGotoHTTP

0x01权限维持-隐藏用户 CreateHiddenAccount工具 CreateHiddenAccount -u test -p Psswrd用户管理能查看到&#xff0c;命令查看看不到&#xff0c;单机版无法删除(不在任何组)&#xff0c;域环境(在administrator组中)可以删除 0x02权限维持-黄金白银票据 ⻩⾦票据⽣成攻…...

动态规划——带权活动选择

带权活动选择Time Limit: 3000 MSMemory Limit: 1000 KB Description 给定n个活动&#xff0c;活动ai表示为一个三元组(si,fi,vi)&#xff0c;其中si表示活动开始时间&#xff0c;fi表示活动的结束时间&#xff0c;vi表示活动的权重, si<fi。带权活动选择问题是选择一些活…...

软考A计划-真题-分类精讲汇总-第十八章(面向对象程序设计)

点击跳转专栏>Unity3D特效百例点击跳转专栏>案例项目实战源码点击跳转专栏>游戏脚本-辅助自动化点击跳转专栏>Android控件全解手册点击跳转专栏>Scratch编程案例 &#x1f449;关于作者 专注于Android/Unity和各种游戏开发技巧&#xff0c;以及各种资源分享&am…...

基于uniapp+WebSocket实现聊天对话、消息监听、消息推送、聊天室等功能,多端兼容

基于 ​UniApp + WebSocket​实现多端兼容的实时通讯系统,涵盖WebSocket连接建立、消息收发机制、多端兼容性配置、消息实时监听等功能,适配​微信小程序、H5、Android、iOS等终端 目录 技术选型分析WebSocket协议优势UniApp跨平台特性WebSocket 基础实现连接管理消息收发连接…...

聊聊 Pulsar:Producer 源码解析

一、前言 Apache Pulsar 是一个企业级的开源分布式消息传递平台&#xff0c;以其高性能、可扩展性和存储计算分离架构在消息队列和流处理领域独树一帜。在 Pulsar 的核心架构中&#xff0c;Producer&#xff08;生产者&#xff09; 是连接客户端应用与消息队列的第一步。生产者…...

vue3 定时器-定义全局方法 vue+ts

1.创建ts文件 路径&#xff1a;src/utils/timer.ts 完整代码&#xff1a; import { onUnmounted } from vuetype TimerCallback (...args: any[]) > voidexport function useGlobalTimer() {const timers: Map<number, NodeJS.Timeout> new Map()// 创建定时器con…...

Axios请求超时重发机制

Axios 超时重新请求实现方案 在 Axios 中实现超时重新请求可以通过以下几种方式&#xff1a; 1. 使用拦截器实现自动重试 import axios from axios;// 创建axios实例 const instance axios.create();// 设置超时时间 instance.defaults.timeout 5000;// 最大重试次数 cons…...

如何理解 IP 数据报中的 TTL?

目录 前言理解 前言 面试灵魂一问&#xff1a;说说对 IP 数据报中 TTL 的理解&#xff1f;我们都知道&#xff0c;IP 数据报由首部和数据两部分组成&#xff0c;首部又分为两部分&#xff1a;固定部分和可变部分&#xff0c;共占 20 字节&#xff0c;而即将讨论的 TTL 就位于首…...

技术栈RabbitMq的介绍和使用

目录 1. 什么是消息队列&#xff1f;2. 消息队列的优点3. RabbitMQ 消息队列概述4. RabbitMQ 安装5. Exchange 四种类型5.1 direct 精准匹配5.2 fanout 广播5.3 topic 正则匹配 6. RabbitMQ 队列模式6.1 简单队列模式6.2 工作队列模式6.3 发布/订阅模式6.4 路由模式6.5 主题模式…...

PAN/FPN

import torch import torch.nn as nn import torch.nn.functional as F import mathclass LowResQueryHighResKVAttention(nn.Module):"""方案 1: 低分辨率特征 (Query) 查询高分辨率特征 (Key, Value).输出分辨率与低分辨率输入相同。"""def __…...

莫兰迪高级灰总结计划简约商务通用PPT模版

莫兰迪高级灰总结计划简约商务通用PPT模版&#xff0c;莫兰迪调色板清新简约工作汇报PPT模版&#xff0c;莫兰迪时尚风极简设计PPT模版&#xff0c;大学生毕业论文答辩PPT模版&#xff0c;莫兰迪配色总结计划简约商务通用PPT模版&#xff0c;莫兰迪商务汇报PPT模版&#xff0c;…...

elementUI点击浏览table所选行数据查看文档

项目场景&#xff1a; table按照要求特定的数据变成按钮可以点击 解决方案&#xff1a; <el-table-columnprop"mlname"label"名称"align"center"width"180"><template slot-scope"scope"><el-buttonv-if&qu…...

论文阅读:LLM4Drive: A Survey of Large Language Models for Autonomous Driving

地址&#xff1a;LLM4Drive: A Survey of Large Language Models for Autonomous Driving 摘要翻译 自动驾驶技术作为推动交通和城市出行变革的催化剂&#xff0c;正从基于规则的系统向数据驱动策略转变。传统的模块化系统受限于级联模块间的累积误差和缺乏灵活性的预设规则。…...