java栈帧里面的储存的内容_java创建一个栈

java栈帧里面的储存的内容_java创建一个栈文章转载自:http://www.tuicool.com/articles/URZrMnbjvm为每个新创建的线程都分配一个堆栈。堆栈以帧为单位保存线程的状态。jvm对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。栈帧(StackFrame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区的虚拟机栈(VirtualMachineStack)的栈元素。栈帧存储了方法的…

大家好,又见面了,我是你们的朋友全栈君。如果您正在找激活码,请点击查看最新教程,关注关注公众号 “全栈程序员社区” 获取激活教程,可能之前旧版本教程已经失效.最新Idea2022.1教程亲测有效,一键激活。

Jetbrains全系列IDE使用 1年只要46元 售后保障 童叟无欺

文章转载自:http://www.tuicool.com/articles/URZrMnb

jvm为每个新创建的线程都分配一个堆栈。堆栈以帧为单位保存线程的状态。jvm对堆栈只进行两种操作:以帧为单位的压栈和出栈操作。

栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,它是虚拟机运行时数据区的虚拟机栈(Virtual Machine Stack)的栈元素。栈帧存储了方法的局部变量表,操作数栈,动态连接和方法返回地址等信息。第一个方法从调用开始到执行完成,就对应着一个栈帧在虚拟机栈中从入栈到出栈的过程。

每一个栈帧都包括了局部变量表,操作数栈,动态连接,方法返回地址和一些额外的附加信息。在编译代码的时候,栈帧中需要多大的局部变量表,多深的操作数栈 都已经完全确定了,并且写入到了方法表的Code属性中,因此一个栈帧需要分配多少内存,不会受到程序运行期变量数据的影响,而仅仅取决于具体虚拟机的实 现

一个线程中的方法调用链可能会很长,很多方法都同时处理执行状态。对于执行引擎来讲,活动线程中,只有虚拟机栈顶的栈帧才是有效的,称为当前栈帧 (Current Stack Frame),这个栈帧所关联的方法称为当前方法(Current Method)。执行引用所运行的所有字节码指令都只针对当前栈帧进行操作。栈帧的概念结构如下图所示:

1a38340824c790f198cdfe80f5e0ac00.png

1.局部变量表

局部变量表是一组变量值存储空间,用于存放方法参数和方法内部定义的局部变量。在Java程序编译为Class文件时,就在方法表的Code属性的max_locals数据项中确定了该方法需要分配的最大局部变量表的容量。

在方法执行时,虚拟机是使用局部变量表完成参数变量列表的传递过程,如果是实例方法,那么局部变量表中的0位索引的Slot默认是用于传递方法所属对象实 例的引用,在方法中可以通过关键字“this”来访问这个隐含的参数,其余参数则按照参数列表的顺序来排列,占用从1开始的局部变量Slot,参数表分配 完毕后,再根据方法体内部定义的变量顺序和作用域来分配其余的Slot。局部变量表中的Slot是可重用的,方法体中定义的变量,其作用域并不一定会覆盖整个方法,如果当前字节码PC计算器的值已经超出了某个变量的作用域,那么这个变量对应的Slot就可以交给其它变量使用。

局部变量不像前面介绍的类变量那样存在“准备阶段”。类变量有两次赋初始值的过程,一次在准备阶段,赋予系统初始值;另外一次在初始化阶段,赋予程序员定义的值。因此 即使在初始化阶段程序员没有为类变量赋值也没有关系,类变量仍然具有一个确定的初始值。但局部变量就不一样了,如果一个局部变量定义了但没有赋初始值是不能使用的。

2.操作数栈

操作数栈也常被称为操作栈,它是一个后入先出栈。同局部变量表一样,操作数栈的最大深度也是编译的时候被写入到方法表的Code属性的 max_stacks数据项中。操作数栈的每一个元素可以是任意Java数据类型,包括long和double。32位数据类型所占的栈容量为1,64位 数据类型所占的栈容量为2。栈容量的单位为“字宽”,对于32位虚拟机来说,一个”字宽“占4个字节,对于64位虚拟机来说,一个”字宽“占8个字节。

当一个方法刚刚执行的时候,这个方法的操作数栈是空的,在方法执行的过程中,会有各种字节码指向操作数栈中写入和提取值,也就是入栈与出栈操作。例如,在做算术运算的时候就是通过操作数栈来进行的,又或者调用其它方法的时候是通过操作数栈来行参数传递的。

另外,在概念模型中,两个栈帧作为虚拟机栈的元素,相互之间是完全独立的,但是大多数虚拟机的实现里都会作一些优化处理,令两个栈帧出现一部分重叠。让下 栈帧的部分操作数栈与上面栈帧的部分局部变量表重叠在一起,这样在进行方法调用返回时就可以共用一部分数据,而无须进行额外的参数复制传递了,重叠过程如 下图:

41782671babda651e6df97551b5bd79e.png

3.动态连接

每个栈帧都包含一个指向运行时常量池中该栈帧所属性方法的引用,持有这个引用是为了支持方法调用过程中的动态连接。在Class文件的常量池中存有大量的 符号引用,字节码中的方法调用指令就以常量池中指向方法的符号引用为参数。这些符号引用一部分会在类加载阶段或第一次使用的时候转化为直接引用,这种转化 称为静态解析。另外一部分将在每一次的运行期期间转化为直接引用,这部分称为动态连接。

4.方法返回地址

当一个方法被执行后,有两种方式退出这个方法。第一种方式是执行引擎遇到任意一个方法返回的字节码指令,这时候可能会有返回值传递给上层的方法调用者(调 用当前方法的的方法称为调用者),是否有返回值和返回值的类型将根据遇到何种方法返回指令来决定,这种退出方法方式称为正常完成出口(Normal Method Invocation Completion)。

另外一种退出方式是,在方法执行过程中遇到了异常,并且这个异常没有在方法体内得到处理,无论是Java虚拟机内部产生的异常,还是代码中使用 athrow字节码指令产生的异常,只要在本方法的异常表中没有搜索到匹配的异常处理器,就会导致方法退出,这种退出方式称为异常完成出口(Abrupt Method Invocation Completion)。一个方法使用异常完成出口的方式退出,是不会给它的调用都产生任何返回值的。

无论采用何种方式退出,在方法退出之前,都需要返回到方法被调用的位置,程序才能继续执行,方法返回时可能需要在栈帧中保存一些信息,用来帮助恢复它的上 层方法的执行状态。一般来说,方法正常退出时,调用者PC计数器的值就可以作为返回地址,栈帧中很可能会保存这个计数器值。而方法异常退出时,返回地址是 要通过异常处理器来确定的,栈帧中一般不会保存这部分信息。

方法退出的过程实际上等同于把当前栈帧出栈,因此退出时可能执行的操作有:恢复上层方法的局部变量表和操作数栈,把返回值(如果有的话)压入调用都栈帧的操作数栈中,调用PC计数器的值以指向方法调用指令后面的一条指令等。

5. 附加信息

虚拟机规范允许具体的虚拟机实现增加一些规范里没有描述的信息到栈帧中,例如与高度相关的信息,这部分信息完全取决于具体的虚拟机实现。在实际开发中,一般会把动态连接,方法返回地址与其它附加信息全部归为一类,称为栈帧信息。

版权声明:本文内容由互联网用户自发贡献,该文观点仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请联系我们举报,一经查实,本站将立刻删除。

发布者:全栈程序员-站长,转载请注明出处:https://javaforall.net/196899.html原文链接:https://javaforall.net

(0)
全栈程序员-站长的头像全栈程序员-站长


相关推荐

  • 阅读软件怎么添加书源_认识一波苹果安卓手机上,那些以一敌百的小说漫画软件…[通俗易懂]

    阅读软件怎么添加书源_认识一波苹果安卓手机上,那些以一敌百的小说漫画软件…[通俗易懂]哈喽大家好,我是无知便是罪,专注于收集和分享互联网上有价值的好东西。今天让我们继续分享一些可以自定义源的软件吧。看过我视频的老用户一听到这个词肯定两眼放光了。像我们之前推荐的看小说的阅读,看漫画的异次元和看影视作品的海阔,他们有一个共同的特点,就是允许用户自定义上传一些书源啦漫画源和影视源。这样你在搜索作品的时候呢,软件就会在这些源头里面进行抓取。如果遇到收费的内容呢,你还可以免费换源,…

    2022年6月20日
    38
  • Java 标识符 命名规则 变量 数据类型

    Java 标识符 命名规则 变量 数据类型Java 语法关键字和保留字关键字 被 java 语言赋予了特殊含义 用作专门的用途的字符串所有关键字都是小写 保留字 现有的 java 版本尚未使用 但是以后版本可能作为关键字使用 gotoconst 标识符标识符 java 对各类变量 方法和类等要素命名时使用的字符序列成为标识符 凡是自己可以命名的地方都叫做标识符 由 16 个英文字母大小写 0 9 或者 和 组成 数字不可以用来开头 不可以使用关键字和保留字 但可以包含关键字和保留字 Java 中严格区分大小写 长度度无限制标识符不

    2025年6月8日
    0
  • HDOJ 5000 Clone

    HDOJ 5000 Clone

    2022年1月4日
    35
  • jsonify返回中文乱码的问题

    jsonify返回中文乱码的问题参考博客:解决flask中文乱码的问题返回内容如图:实际填写的内容:从网上找答案,结果很多都是说配置app.config,如下:app.config[‘JSON_AS_ASCII’]但我试了之后,还是不可能正常显示汉字,最终还是通过配置app.config解决,只是增加了一这一项:参考博客:PythonWEB框架之Flask…

    2022年5月16日
    41
  • 分类结果评价指标——Kappa系数

    分类结果评价指标——Kappa系数kappa系数是用来衡量两个变量一致性的指标,如果将两个变量换为分类结果和验证样本,就可以用来评价分类精度了。计算公式如下:kappa=(Po-Pe)/(1-Pe)其中,Po是总体精度,Pe是偶然

    2022年7月2日
    31
  • EXCEL宏编程纪念

    EXCEL宏编程纪念       不久前被叫去编写宏,这EXCEL宏真是麻烦! 可能以后不会再遇到有编写宏的经历了,故而贴出来以做个纪念: Subdirect_Price()query_dir_volume宏由颜清国编写,时间:2007-4-9定义变量DimcRowsAsInteger总行数DimcColumnsAsInteger总列数DimHEADERCOLORINDE

    2022年5月5日
    38

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注

关注全栈程序员社区公众号