JVM-虚拟机栈概述

a6d03e261a684f4f9060cc4bd1c19334.jpg

 

背景:由于跨平台的设计,java指令都是根据栈来设计的。不同平台CPU架构不同,所以不能设计为基于寄存器。

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

栈中可能出现的异常:java栈的大小可以是动态的也可以是固定不变的。

如果采用固定大小的虚拟机栈,那么如果线程请求超过栈容量,会出现StackOverflowError异常。

如果java虚拟机可以动态扩展,当无法申请扩展到足够的内存的时候,会抛出OOM(OutOfMemoryError)异常。

栈的运行原理:

JVM直接堆Java栈的操作只有两个,就是入栈和出栈,遵循先进后出的原则,所以没有GC(垃圾回收)。

java栈中存储的数据是栈帧,一个活动线程的一个时间点上只有一个活动的栈帧,如果在方法中调用了其他方法,那么新的栈帧会被创建出来,放在栈的顶端,成为新的栈帧。

不同线程中所包含的栈帧是不允许存在相互引用的,即不可能在一个栈帧之中引用另外一个线程的栈帧。

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

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

栈的内部结构:

1)局部变量表

2)操作数栈

3)动态链接

4)方法返回地址

5)一些附加信息

2 局部变量表

定义为一个数字数字,主要用于存储方法参数和定义在方法体内的局部变量。

因为时定义在线程私有的虚拟机栈上,所以很多时候不存在线程安全问题(当局部变量作为函数参数传递一点点牵强)、作为函数返回值时会出现线程安全问题)。

局部变量表所需的容量大小是在编译期间确定下来的,并保存在方法的Code 属性的maximum local variables数据项中。在方法运行期间是不会改变局部变量表的大小。

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

Slot:

局部变量表的最基本的存储单元就是slot(槽)

在局部变量表里,32位以内的类型只占用一个slot(包括returnAddress类型)-存储的时候都是以int类型存储,64位的类型(long和double)占用两个slot。

jvm会为局部变量中每一个slot都分配一个访问索引,通过整访问索引可以成功范文到局部变量表中指定的局部变量

如果当前帧时由构造方法或者实例方法创建的(非静态方法),那么该对象的引用this将会存放在index为0的slot处。

 

slot的 重复利用:

栈帧中的局部变量表中的槽位时可以重复利用的,如果一个局部变量过了其作用域(如类里面的代码块),后面申请的局部变量就可能重复利用过期的局部变量的槽位。

 

局部变量与静态变量的对比:

静态变量的初始化有两个阶段,第一次是在准备阶段,会对其分配存储空间和默认的初始化值,第二次是在初始化阶段,赋予程序员在代码中定义的初始值。

局部变量不存在系统初始化的过程,所以一旦定义,必须认为进行初始化,不然无法使用。

3 操作数栈

操作数栈,在方法执行过程中,根据字节码指令,往栈中写入数据或提取数据。主要用于保存计算结果过程的中间结果,同时作为计算过程中的变量临时的存储空间。

操作数栈中可以存储任意类似的java数据,32bit的类型占用一个栈单位深度,64位的类型占用两个栈单位深度。

如果调用的方法带有返回值,其返回值会被压入当前栈帧的操作数据栈中,并更新PC寄存器中下一条需要执行的字节码指令。

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

4 动态链接

每一个栈帧内部都包含一个指向运行时常量池中该栈帧所属的方法的引用。包含这个引用的目的就是支持当前方法的代码能够实现动态链接。比如invokedynamic指令。java属于静态语言,是判断变量本身类型信息,java8中lambda的出现,invokedynamic指令的生成,使得java有了直接生成的方式,有了一个动态语言的特性。

在java源文件被编译到字节码文件中时,所有变量和方法引用都作为符号引用保存在class文件的常量池里,动态链接就是为了将这些符号引用转换位调用方法的直接引用。

5 方法调用

在jvm中,将符号引用转换位调用方法的直接引用与方法的绑定机制相关。

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

动态链接:如果被调用的方法在编译期无法被确定下来,也就是说,只能够在程序运行期间将调用方法的符号引用转化位直接引用。

 

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

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

YOLO建筑物损伤评估数据集

YOLO建筑物损伤评估数据集,重度损伤,轻微损伤,中度损伤,未损伤4类,近五千张图像,yolo标注完整,应用数据增强。 适用于CV项目,毕设,科研,实验等 需要此数据集…

老司机都懂的!【打赏】完美运营的最新视频打赏系统

完美运营的最新视频打赏系统优于市面上95%的打赏系统,与其他打赏系统相比,功能更加强大,完美运营且无bug。支付会调、短链接生成、代理后台、价格设置和试看功能等均没有问题。 以上为原简介,经测试验证。成功搭建并可以正常进入…

leetcode 热题 100_除自身以外数组的乘积

题解一: 前缀 / 后缀数组:某元素除自身以外的乘积,也就是其全部前缀元素乘积 * 全部后缀元素乘积,因此我们可以构造前缀数组和后缀数组,分别存储前i个元素的成绩和后i个元素的乘积,再将i-1前缀乘积 * i1后缀…

哨兵系列数据下载(哨兵2号Sentinel-2下载)

目录 一、介绍 二、哨兵二号介绍 三、数据下载 1、注册账号 2、数据下载 3、相关问题 四、数据预处理 1、大气校正 2、重采样 五、其他问题 一、介绍 哨兵-1卫星是全天时、全天候雷达成像任务,用于陆地和海洋观测,首颗哨兵&#xf…

解答关于:水牛社软件是做什么的?水牛社软件靠谱么?

很多对我们软件感兴趣但是没有入手的观望者都会有这样的疑问:水牛社软件具体是做什么的?水牛社软件靠谱么? 其实软件的简介已经讲的很清楚了,但是软件不是功能性软件,所以不能给大家免费试用,短期任务版块…

go语言添加代理

LiteIDE 工具->管理 https://mirrors.aliyun.com/goproxy/或https://goproxy.cn,direct 命令行 go env -w GOPROXYhttps://goproxy.cn,direct

深度学习与人类的智能交互:迈向自然与高效的人机新纪元

引言 随着科技的飞速发展,深度学习作为人工智能领域的一颗璀璨明珠,正日益展现出其在模拟人类认知和感知过程中的强大能力。本文旨在探讨深度学习如何日益逼近人类智能的边界,并通过模拟人类的感知系统,使机器能更深入地理解和解…

freeRTOS20240308

1.总结任务的调度算法,把实现代码再写一下 2.总结任务的状态以及是怎么样进行转换的

js【详解】原型 vs 原型链

原型 每个 class 都有显示原型 prototype每个实例都有隐式原型_proto_实例的_proto_指向对应 class 的 prototype 如下范例: class Student 创建了 实例 xialuo 获取属性 xialuo.name 或执行方法 xialuo.sayhi()时,先在自身属性和方法寻找&#xff0…

云轴科技ZStack荣获证券基金行业信息技术应用创新联盟年度优秀成员奖

近日,由中国证监会科技监管司、上海市经济和信息化委员会及上交所理事会科技发展委员会指导,证券基金行业信息技术应用创新联盟(简称信创联盟)主办的2023年年度工作会议在上海成功举办。会议汇聚了来自监管机构、政府机构、行业侧…

JavaWeb——014SpringBoot原理(配置优先级、Bean管理、SpringBoot原理)

SpingBoot原理 目录 SpingBoot原理1. 配置优先级2. Bean管理2.1 获取Bean2.2 Bean作用域2.3 第三方Bean 3. SpringBoot原理3.1 起步依赖3.2 自动配置3.2.1 概述3.2.2 常见方案3.2.2.1 概述3.2.2.2 方案一3.2.2.3 方案二 3.2.3 原理分析3.2.3.1 源码跟踪3.2.3.2 Conditional 3.2…

软件测试【测试用例设计】面试题详解

前言 今天笔者想和大家来聊聊测试用例,这篇文章主要是想要写给测试小伙伴们的,因为我发现还是有很多小伙伴在遇到写测试用例的时候无从下手,我就想和大家简单的聊聊,这篇文章主要是针对功能测试的。 一、微信功能测试 1.点击点…