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

JVM运行时数据区-虚拟机栈

目录

一、内存中的栈

二、基本内容

三、优点

四、栈的存储单位

五、栈运行原理

六、栈的内部结构

(一)局部变量表

(二)操作数栈

(三)动态链接

(四)方法返回地址

(五)附加信息

(六)方法的调用

1、链接方式

2、方法的绑定

3、虚方法和非虚方法

4、方法调用指令

5、方法重写的本质

6、虚方法表


这次学习的是JVM运行时数据区中的Java虚拟机栈部分

一、内存中的栈

栈是运行时的单位,而堆是存储的单位,栈解决程序如何执行,如何处理数据。堆解决的是数据存储问题,即数据怎么放,放在哪里。

二、基本内容

  • Java虚拟机栈,早期也叫Java栈,每个线程创建时都会创建一个虚拟机栈,内部保存一个个栈帧,对应着一次次的Java方法调用
  • 生命周期和线程的一致
  • 主管Java程序的运行,保存方法的局部变量(8种基本数据类型,对象的引用地址),部分结果,并参与方法的调用和返回。
    • 局部变量  vs  成员变量
    • 基本数据类型   VS 引用类型变量(类,数组,接口)

三、优点

1、快速有效的存储方式,访问速度仅次于程序计数器

2、JVM直接对JAVA栈的操作只有两个

  • 每个方法执行,伴随着进栈(入栈,压栈)
  • 执行结束的出栈

3、栈不存在垃圾回收,但是存在OOM

4、Java栈大小是动态或者固定不变的。如果是动态扩展,无法申请到足够内存OOM,如果是固定,线程请求的栈容量超过固定值,则StackOverflowError

5、使用-Xss (记忆:站着做一个小手术,栈Xss),设置线程的最大栈空间

四、栈的存储单位

  1. 每个线程都有自己的栈,栈中的数据以栈帧格式存储
  2. 线程上正在执行的每个方法都各自对应一个栈帧
  3. 栈帧是一个内存区块,是一个数据集,维系着方法执行过程中的各个数据信息
  4. 先进后出,后进先出
  5. 一条活动的线程中,一个时间点上,只会有一个活动的栈帧。只有当前正在执行的方法的栈顶栈帧是有效的,这个称为当前栈帧,对应方法是当前方法,对应类是当前类
  6. 执行引擎运行的所有字节码指令只针对当前栈帧进行操作
  7. 如果方法中调用了其他方法,对应的新的栈帧会被创建出来,放在顶端,成为新的当前帧

五、栈运行原理

不同线程中包含的栈帧不允许存在相互引用。

当前方法调用了其他方法,方法返回之际,当前栈帧会传回此方法的执行结果给前一个栈帧,接着虚拟机会丢弃当前栈帧,使得前一个栈帧重新成为新的栈帧。

Java方法有两种返回方式

  • 一种是正常的函数返回,使用return指令
  • 另外一种是抛出异常,不管哪种方式,都会导致栈帧被弹出

六、栈的内部结构

栈中存储栈帧,每个栈帧中存储着:

① 局部变量表

② 操作数栈

③ 动态链接

④ 方法返回地址

⑤ 一些附加信息

(一)局部变量表

1、定义为一个数字数组,主要用于存储方法参数,定义在方法体内部的局部变量,数据类型包括各类基本数据类型,对象引用,以及return address类型

2、局部变量表建立在线程的栈上,是线程私有的,因此不存在数据安全问题

3、局部变量表容量大小是在编译期确定下来的

4、局部变量表存放编译期可知的各种基本数据类型(8种),引用类型(reference),return address 类型

5、最基本的存储单元是slot,32位占用一个slot,64位类型(long和double)占用两个slot

6、局部变量表中的变量只有在当前方法调用中有效,虚拟机通过使用局部变量表完成参数值到参数变量列表的传递过程。方法调用结束后,随着方法栈帧的销毁,局部变量表也会随之销毁

7、关于Slot的理解

  • JVM虚拟机会为局部变量表中的每个Slot都分配一个访问索引,通过这个索引即可成功访问到局部变量表中指定的局部变量值
  • 如果当前帧是由构造方法或者实例方法创建的,那么该对象引用this,会存放在index为0的slot处,其余的参数表顺序继续排列

补充:

在栈帧中,与性能调优关系最密切的部分,就是局部变量表,方法执行时,虚拟机使用局部变量表完成方法的传递

局部变量表中的变量也是重要的垃圾回收根节点,只要被局部变量表中直接或间接引用的对象都不会被回收

(二)操作数栈

在方法执行的过程中,根据字节码指令,往栈中写入数据或提取数据,即入栈/出栈

1、如果被调用方法带有返回值的话,其返回值将会被压入当前栈帧的操作数栈中,并更新程序计数器中下一条需要执行的字节码指令

2、Java虚拟机的解释引擎是基于栈的执行引擎,其中栈就是操作数栈

3、主要用于保存计算过程的中间结果,同时作为计算过程中变量临时的存储空间

4、当一个方法刚开始执行的时候,一个新的栈帧也会随之被创建出来,这个方法的操作数栈是空的

5、每一个操作数栈会拥有一个明确的栈深度,用于存储数值,最大深度在编译期就定义好

6、栈中,32bit类型占用一个栈单位深度,64bit类型占用两个栈单位深度(和局部变量表中Slot存储相同)

7、操作数栈并非采用访问索引方式进行数据访问,而是只能通过标准的入栈、出栈操作完成一次数据访问

8、栈顶缓存技术

由于操作数是存储在内存中,频繁的进行内存读写操作影响执行速度,将栈顶元素全部缓存到物理CPU的寄存器中,依此降低对内存的读写次数,提升执行引擎的执行效率

(三)动态链接

指向运行时常量池的方法引用(运行时常量池放在方法区中)

  • 每一个栈帧内部都包含一个指向运行时常量池中,该帧所属方法的引用
  • 目的是为了支持当前方法的代码能够实现动态链接,比如invokedynamic指令
  • 在java源文件被编译成字节码文件中时,所有的变量、方法引用都作为符号引用,保存在class文件的常量池中。
  • 描述一个方法调用了另外的其他方法时,就是通过常量池中指向方法的符号引用来表示的。
  • 动态链接的作用就是为了将这些符号引用转换为调用方法的直接引用

常量池、运行时常量池

  • 常量池在字节码文件中,运行时常量池,在运行时的方法区中

(四)方法返回地址

1、存放调用该方法的pc寄存器的值

2、方法的结束

  • 正常执行完成
  • 出现未处理异常,非正常退出

3、无论哪种方式退出,方法退出后,都会返回该方法被调用的位置。方法正常退出时,调用者的PC计数器的值作为返回地址,即调用该方法的指令的下一条指令的地址。

4、异常退出的,返回地址是通过异常表来确定,栈帧中一般不会保存这部分信息

5、执行引擎遇到任意一个方法返回的字节码指令(return),会有返回值传递给上层的方法调用者,简称正常完成出口。返回指令包括:

  • ireturn返回值是boolean,byte,char,short,和int类型时使用
  • lreturn——long
  • dreturn——double
  • areturn——引用类型
  • 还有一个return指供声明为 void的方法、实例初始化方法、类和接口的初始化方法使用

6、本质上,方法的退出就是当前栈帧出栈的过程。此时需要恢复上层方法的局部变量表,操作数栈,将返回值压入调用者栈帧的操作数栈,设置PC寄存器值等,让调用者方法继续执行下去。

7、正常完成出口和异常完成出口的区别在于:通过异常完成出口退出的不会给他的上层调用者产生任何的返回值

(五)附加信息

允许携带与Java虚拟机实现相关的一些附加信息,例如对程序调试提供支持的信息。不一定每个栈帧都有,所以说栈帧主要包含局部变量表、操作数栈、动态链接和方法返回地址的说法其实也没错。

(六)方法的调用

1、链接方式

① 静态链接

当一个字节码文件被装载进JVM内部时,如果被调用的目标方法在编译期可知,且运行时期间保持不变,这种情况下降调用方的符号引用转为直接引用的过程称为静态链接

② 动态链接

如果被调用的方法无法再编译期被确定下来,只能在运行期将调用的方法的符号引用转为直接引用,这种引用转换过程具备动态性,因此被称为动态链接

2、方法的绑定

绑定是一个字段、方法、或者类在符号引用被替换为直接引用的过程。仅仅发生一次。

① 早期绑定

被调用的目标方法如果再编译期可知,且运行期保持不变

② 晚期绑定

被调用的方法在编译期无法被确定,只能够在程序运行期根据实际的类型绑定相关的方法。

Java中任何一个普通方法都具备虚函数的特征(运行期确认,具备晚期绑定的特点),C++中则使用关键字virtual来显式定义

如果在java程序中,不希望某个方法拥有虚函数的特征,则可以使用关键字final来标记这个方法

3、虚方法和非虚方法

① 非虚方法

如果方法在编译期就确定了具体的调用版本,则这个版本在运行时是不可变的。这样的方法称为非虚方法

静态方法,私有方法,final方法,实例构造器,父类方法都是非虚方法

② 除了非虚方法,其他方法称为虚方法

4、方法调用指令

① 普通调用指令

  • invokestatic          调用静态方法,解析阶段确定唯一方法版本
  • invokespecial          调用<init>方法,私有及父类方法,解析阶段确定唯一方法版本
  • invokevirtual        调用所有虚方法
  • invokeinterface           调用接口方法
  • 其中invokestatic指令和invokespecial指令调用的方法称为非虚方法,其余的(final修饰的除外)称为虚方法 

② 动态调用指令

  • invokedynamic         动态解析出需要调用的方法,然后执行

直到Java8的Lambda表达式的出现,invokedynamic指令的生成,在Java中才有了直接的生成方式。Java本身是静态语言,动态调用指令使Java有了动态语言的特性

5、方法重写的本质

① 找到操作数栈顶的第一个元素所执行的对象的实际类型,记做C

② 如果在类型C中找到与常量池中描述符和简单名称都相符的方法,则进行访问权限校验,如果通过则返回这个方法的直接引用,查找过程结束,如果不通过,则返回java.lang.IllegalAccessError异常

③ 否则,按照继承关系从下往上依次对C的各个父类进行上一步的搜索和验证过程。

④ 如果始终没有找到合适的方法,则抛出java.lang.AbstractMethodError异常

6、虚方法表

面向对象的编程中,会很频繁的使用动态分配,如果每次动态分配的过程都要重新在类的方法元数据中搜索合适的目标的话,就可能影响到执行效率,因此为了提高性能,JVM采用在类的方法区建立一个虚方法表,使用索引表来代替查找

每个类都有一个虚方法表,表中存放着各个方法的实际入口

虚方法表会在类加载的链接阶段被创建,并开始初始化,类的变量初始值准备完成之后,JVM会把该类的方法也初始化完毕

相关文章:

JVM运行时数据区-虚拟机栈

目录 一、内存中的栈 二、基本内容 三、优点 四、栈的存储单位 五、栈运行原理 六、栈的内部结构 &#xff08;一&#xff09;局部变量表 &#xff08;二&#xff09;操作数栈 &#xff08;三&#xff09;动态链接 &#xff08;四&#xff09;方法返回地址 &#xf…...

Java中介者模式

目录 定义 结构 案例 优点 缺点 使用场景 定义 又叫调停模式&#xff0c;定义一个中介角色来封装一系列对象之间的交互&#xff0c;使原有对象之间的耦合松散&#xff0c;且可以独立地改变它们之间的交互。 结构 中介者模式包含以下主要角色&#xff1a; 抽象中介者角…...

前端框架Vue学习 ——(五)前端工程化Vue-cli脚手架

文章目录 Vue-cliVue项目-创建Vue项目-目录结构Vue项目-启动Vue项目-配置端口Vue项目开发流程 Vue-cli 介绍&#xff1a;Vue-cli 是 Vue 官方提供的一个脚手架&#xff0c;用于快速生成一个 Vue 的项目模版 安装 NodeJS安装 Vue-cli npm install -g vue/cliVue项目-创建 图…...

App备案-iOS云管理式证书 Distribution Managed 公钥及证书SHA-1指纹的获取方法

根据近日工业和信息化部发布的《工业和信息化部关于开展移动互联网应用程序备案工作的通知》&#xff0c;相信不少要进行IOS平台App备案的朋友遇到了一个问题&#xff0c;就是apple不提供云管理式证书的下载&#xff0c;也就无法获取公钥及证书SHA-1指纹。 已经上架的应用不想重…...

Spring -Spring之依赖注入源码解析

依赖注入底层原理流程图&#xff1a;Spring中Bean的依赖注入原理| ProcessOn免费在线作图,在线流程图,在线思维导图 Spring中到底有几种依赖注入的方式&#xff1f; 首先分两种&#xff1a; 手动注入自动注入 手动注入 在XML中定义Bean时&#xff0c;就是手动注入&#xf…...

Spire.Office for .NET 8.10.2 同步更新-Crk

Spire.Office for .NET是 E-iceblue 提供的企业级 Office .NET API 的组合。它包括Spire.Doc、Spire.XLS、Spire.Spreadsheet、Spire.Presentation、Spire.PDF、Spire.DataExport、Spire.OfficeViewer、Spire.PDFViewer、Spire.DocViewer、Spire.Barcode和Spire.Email。Spire.O…...

MFC 基础篇(一)

目录 一.SDK编程 二.为什么要学MFC&#xff1f; 三.MFC能做什么&#xff1f; 四.MFC开发环境搭建 五.MFC项目创建 六.消息映射机制 一.SDK编程 Application Programming Interface 应用程序编程接口。 Software Development Kit 软件开发工具包&#xff0c;一般会包括A…...

Android技术-修改SO导出符号

背景 经常在使用第三方SDK的时候会莫名其妙报错&#xff0c;其中最常见的一种就是SO符号冲突&#xff0c;比如libA.so静态链接了libC.a,而libB.so动态链接了libC.so。这样便会导致符号冲突。又或者在使用不同版本的动态库&#xff0c;也会造成符号冲突。 报错案例 案例1 DEB…...

flutter 打包apk

Flutter项目打包生成APK_flutter打包apk_文阿花的博客-CSDN博客 关于iconData可能出现的错误&#xff1a; flutter build apk 打包报错调试过程 - 掘金 (juejin.cn) 使用命令行&#xff1a;flutter build apk --no-tree-shake-icons...

Halcon如何使用SaperaLT库连接dalsa相机

halcon安装好的时候&#xff0c;没有带SaperaLT的采集库&#xff0c;需要额外在Halcon官网下载此库。 以下是halcon官网下载此库的链接。官网需要注册才可以下载。 https://www.mvtec.com/downloads/interfaces?tx_mvtecproduct_extensiondownloadlist%5Bfilter%5D%5B0%5Dma…...

Vue 嵌套路由 多级路由规则

套娃路由 routes:[{path: /login,component: Login},{path: /user,component: User,children:[{ path: test, component: Test },{ path: test2, component: Test2 },]}]子路由不需要加/ 在父组件 子路由不需要加/ 需要带上父亲的路由路径 <router-link to"user/test…...

pandas教程:Introduction to pandas Data Structures pandas的数据结构

文章目录 Chapter 5 Getting Started with pandas5.1 Introduction to pandas Data Structures1 Series2 DataFrame3 Index Objects (索引对象) Chapter 5 Getting Started with pandas 这样导入pandas&#xff1a; import pandas as pde:\python3.7\lib\site-packages\numpy…...

MinIO 分布式文件(对象)存储

简介 MinIO是高性能、可扩展、云原生支持、操作简单、开源的分布式对象存储产品。 在中国&#xff1a;阿里巴巴、腾讯、百度、中国联通、华为、中国移动等等9000多家企业也都在使用MinIO产品 官网地址&#xff1a;http://www.minio.org.cn/ 下载 官网下载(8.4.3版本)&#x…...

HTML表单标签

## HTML标签&#xff1a;表单标签 * 表单&#xff1a; * 概念&#xff1a;用于采集用户输入的数据的。用于和服务器进行交互。 * form&#xff1a;用于定义表单的。可以定义一个范围&#xff0c;范围代表采集用户数据的范围 * 属性&#xff1…...

【黑马程序员】SpringCloud——Eureka

文章目录 前言一、提供者与消费者1. 服务调用关系 二、远程调用的问题三、eureka 原理分析1. eureka 的作用 四、Eureka 案例1. 搭建 eureka 服务1. 服务注册1.1 注册 user-service1.2 启动 user-service3. order-service 完成服务注册 3. 服务发现1. 在 order-service 完成服务…...

目标跟踪(DeepSORT)

本文首先将介绍在目标跟踪任务中常用的匈牙利算法&#xff08;Hungarian Algorithm&#xff09;和卡尔曼滤波&#xff08;Kalman Filter&#xff09;&#xff0c;然后介绍经典算法DeepSORT的工作流程以及对相关源码进行解析。 目前主流的目标跟踪算法都是基于Tracking-by-Detec…...

2 任务2: 使用趋动云GPU进行猫狗识别实践

使用趋动云GPU进行猫狗识别实践 1 创建项目2 初始化开发环境3 调试代码4 提交离线任务5 结果集存储与下载 使用趋动云提供的免费GPU&#xff0c;进行猫狗识别实践。 虽然例程里面提供的是基于tensorflow的&#xff0c;但是你也可以使用pytorch的代码 使用这个平台的一个优点就是…...

技术分享 | app自动化测试(Android)--显式等待机制

WebDriverWait类解析 WebDriverWait 用法代码 Python 版本 WebDriverWait( driver,timeout,poll_frequency0.5,ignored_exceptionsNone) 参数解析&#xff1a; driver&#xff1a;WebDriver 实例对象 timeout: 最长等待时间&#xff0c;单位秒 poll_frequency: 检测的间…...

机器学习基础之《回归与聚类算法(5)—分类的评估方法》

问题&#xff1a;上一篇的案例&#xff0c;真的患癌症的&#xff0c;能被检查出来的概率&#xff1f; 一、精确率和召回率 1、混淆矩阵 在分类任务下&#xff0c;预测结果(Predicted Condition)与正确标记(True Condition)之间存在四种不同的组合&#xff0c;构成混淆矩阵(适…...

如何在macbook上删除文件?Mac删除文件的多种方法

在使用MacBook电脑时&#xff0c;桌面上经常会积累大量的文件&#xff0c;而这些文件可能已经不再需要或已经过时。为了保持桌面的整洁和提高电脑性能&#xff0c;我们需要及时删除这些文件。本文将介绍MacBook怎么删除桌面文件&#xff0c;以及macbook删除桌面文件快捷键。 一…...

Ubuntu系统下交叉编译openssl

一、参考资料 OpenSSL&&libcurl库的交叉编译 - hesetone - 博客园 二、准备工作 1. 编译环境 宿主机&#xff1a;Ubuntu 20.04.6 LTSHost&#xff1a;ARM32位交叉编译器&#xff1a;arm-linux-gnueabihf-gcc-11.1.0 2. 设置交叉编译工具链 在交叉编译之前&#x…...

uni-app学习笔记二十二---使用vite.config.js全局导入常用依赖

在前面的练习中&#xff0c;每个页面需要使用ref&#xff0c;onShow等生命周期钩子函数时都需要像下面这样导入 import {onMounted, ref} from "vue" 如果不想每个页面都导入&#xff0c;需要使用node.js命令npm安装unplugin-auto-import npm install unplugin-au…...

家政维修平台实战20:权限设计

目录 1 获取工人信息2 搭建工人入口3 权限判断总结 目前我们已经搭建好了基础的用户体系&#xff0c;主要是分成几个表&#xff0c;用户表我们是记录用户的基础信息&#xff0c;包括手机、昵称、头像。而工人和员工各有各的表。那么就有一个问题&#xff0c;不同的角色&#xf…...

React19源码系列之 事件插件系统

事件类别 事件类型 定义 文档 Event Event 接口表示在 EventTarget 上出现的事件。 Event - Web API | MDN UIEvent UIEvent 接口表示简单的用户界面事件。 UIEvent - Web API | MDN KeyboardEvent KeyboardEvent 对象描述了用户与键盘的交互。 KeyboardEvent - Web…...

python爬虫:Newspaper3k 的详细使用(好用的新闻网站文章抓取和解析的Python库)

更多内容请见: 爬虫和逆向教程-专栏介绍和目录 文章目录 一、Newspaper3k 概述1.1 Newspaper3k 介绍1.2 主要功能1.3 典型应用场景1.4 安装二、基本用法2.2 提取单篇文章的内容2.2 处理多篇文档三、高级选项3.1 自定义配置3.2 分析文章情感四、实战案例4.1 构建新闻摘要聚合器…...

【C语言练习】080. 使用C语言实现简单的数据库操作

080. 使用C语言实现简单的数据库操作 080. 使用C语言实现简单的数据库操作使用原生APIODBC接口第三方库ORM框架文件模拟1. 安装SQLite2. 示例代码:使用SQLite创建数据库、表和插入数据3. 编译和运行4. 示例运行输出:5. 注意事项6. 总结080. 使用C语言实现简单的数据库操作 在…...

成都鼎讯硬核科技!雷达目标与干扰模拟器,以卓越性能制胜电磁频谱战

在现代战争中&#xff0c;电磁频谱已成为继陆、海、空、天之后的 “第五维战场”&#xff0c;雷达作为电磁频谱领域的关键装备&#xff0c;其干扰与抗干扰能力的较量&#xff0c;直接影响着战争的胜负走向。由成都鼎讯科技匠心打造的雷达目标与干扰模拟器&#xff0c;凭借数字射…...

Device Mapper 机制

Device Mapper 机制详解 Device Mapper&#xff08;简称 DM&#xff09;是 Linux 内核中的一套通用块设备映射框架&#xff0c;为 LVM、加密磁盘、RAID 等提供底层支持。本文将详细介绍 Device Mapper 的原理、实现、内核配置、常用工具、操作测试流程&#xff0c;并配以详细的…...

算法岗面试经验分享-大模型篇

文章目录 A 基础语言模型A.1 TransformerA.2 Bert B 大语言模型结构B.1 GPTB.2 LLamaB.3 ChatGLMB.4 Qwen C 大语言模型微调C.1 Fine-tuningC.2 Adapter-tuningC.3 Prefix-tuningC.4 P-tuningC.5 LoRA A 基础语言模型 A.1 Transformer &#xff08;1&#xff09;资源 论文&a…...

SQL慢可能是触发了ring buffer

简介 最近在进行 postgresql 性能排查的时候,发现 PG 在某一个时间并行执行的 SQL 变得特别慢。最后通过监控监观察到并行发起得时间 buffers_alloc 就急速上升,且低水位伴随在整个慢 SQL,一直是 buferIO 的等待事件,此时也没有其他会话的争抢。SQL 虽然不是高效 SQL ,但…...