请选择 进入手机版 | 继续访问电脑版
搜索
房产
装修
汽车
婚嫁
健康
理财
旅游
美食
跳蚤
二手房
租房
招聘
二手车
教育
茶座
我要买房
买东西
装修家居
交友
职场
生活
网购
亲子
情感
龙城车友
找美食
谈婚论嫁
美女
兴趣
八卦
宠物
手机

详细解析Java虚拟机的栈帧结构

[复制链接]
查看: 17|回复: 0

2万

主题

3万

帖子

8万

积分

管理员

Rank: 9Rank: 9Rank: 9

积分
81333
发表于 2020-1-14 14:36 | 显示全部楼层 |阅读模式
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
什么是栈帧?

正如大家所了解的,Java捏造机的内存地域被别离为步伐计数器、捏造机栈、当地方式栈、堆和方式区。(什么?你还不晓得,赶紧去看看《Java捏造机内存结构及编码实战》)此主要先容的栈帧(Stack Frame),就是Java捏造机中的捏造机栈(Virtual Machine Stack)的底子元素,它也是用于支持Java捏造机举行方式挪用和方式实行背后的数据结构,了解了它便可以更好地大白Java捏造机实行引擎是怎样运转的。
每一个方式从挪用起头至实行竣事的全部进程,都对应着一个栈帧在捏造机栈中从入栈到出栈的进程。栈帧存储了方式的部分变量表、操纵数栈、静态毗连和方式返回地址等信息,在同一时辰、同一条线程中,只要位于栈顶的方式才是在运转的,只要位于栈顶的栈帧才是生效的,实行引擎所运转的全数字节码指令都只针对当前栈帧举行操纵。捏造机栈和栈帧的整体结构以下图:
详细解析Java虚拟机的栈帧结构  游戏

接下来,再别离先容一下栈帧中的部分变量表、操纵数栈、静态毗连、方式返回地址等各个部分的感化和数据结构。
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
部分变量表(Local Variables Table)

部分变量表是用来存储一组变量值的内存空间,用于寄存方式参数和方式内部界说的部分变量。在已经编译好的Class文件中,方式的Code属性的max_locals数据项中,就肯定了该方式所需分派的部分变量表的最大容量。
部分变量表的容量以变量槽(Variable Slot)为最小单元,每个变量槽寄存一个32位数据典范,如boolean、byte、char、short、int、float和reference这几种典范。前6种典范同学们应当都了解,就不必多先容了,reference典范表现对一个工具实例的援用,经过这个援用做到两件事变:按照援用间接或间接地查找到实例在Java堆中的数据寄存的肇端地或索引;按照援用间接或间接地查找到在方式区中的存储的类信息。对于64位数据典范,如long和double这两种典范,是以高位对齐的方式为其分派两个连续的变量槽空间。
利用部分变量表时,经过索引定位对应数据的位置,索引值的范围是从0起头至部分变量表最大的变量槽数目。假如拜候的是32位数据典范的变量,索引N就代表了利用第N个变量槽,假如拜候的是64位数据典范的变量,则分析会同时利用第N和N+1两个变量槽。对于两个相邻的配合寄存一个64位数据的两个变量槽,捏造机不答应采纳任何方式零丁拜候其中的某一个,假如碰到举行这类操纵的字节码,Java捏造机就会在类加载的校验阶段中抛出很是。
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
当一个方式被挪用时,会利用部分变量表来完成参数值到参数变量列表的转达进程。假照实行的是工具实例的成员方式(没有被static修饰的方式),那末部分变量表中第0位索引的变量槽默许就是该工具实例的援用,在方式中可以经过关键字this来拜候到这个隐含的参数。此外参数则依照参数表顺序排列,参数表分派终了后,再按照方式体内部界说的部分变量顺序和感化域分派此外的变量槽。为了尽大要节省栈帧所耗的内存空间,部分变量表中的变量槽是可以重用的,当方式体中界说的部分变量超越其感化域时,该部分变量对应的变量槽便可以交给其他变量来重用。
之前的《JVM的类加载机制详解》中先容过,在类加载进程中,类变量有两次赋初始值的进程,一次在预备阶段,赋予系统初始值;此外一次在初始化阶段,赋予代码中界说的初始值。是以即使没有为类变量赋值也没有关系,类变量仍然具有一个肯定的初始值,不会发生歧义。可是部分变量不像类变量有那样的“预备阶段”,假如一个部分变量界说了但没有赋初始值,那它是完全不能利用的。所以不要以为Java中任何情况下都存在诸如整型变量默以为0、布尔型变量默以为false等这样的默许值法则。比如:
  1. public class OneMoreStudy {    public static void main(String[] args) {        int i;        System.out.println(i);    }}
复制代码
由于部分变量i没有初始,在编译进程就会报错:
  1. Error:(4, 28) java: 大要尚未初始化变量i
复制代码
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
操纵数栈(Operand Stack)

操纵数栈是一个后入先出(Last In First Out,LIFO)栈。和部分变量表一样,在已经编译好的Class文件中,方式的Code属性的max_stacks数据项中,就肯定了该方式所需分派的操纵数栈的最大深度。在方式实行的任何时候,操纵数栈的深度都不会横跨在max_stacks数据项中设定的最大值。操纵数栈的每一个元素都可所以包含long和double在内的尽情Java数据典范。32位数据典范所占的栈容量为1,64位数据典范所占的栈容量为2。
当一个方式刚刚起头实行的时候,该方式的操纵数栈是空的,在该方式的实行进程中,会有各类字节码指令对操纵数栈举行出栈和入栈的操纵。比如,整数加法的字节码指令iadd,在该指令实行前必须保证操纵数栈中最靠近栈顶的两个元素已经存入了两个int型的数值,当该指令实行时,会把这两个int值出栈并相加,然后将相加的结果重新入栈。
操纵数栈中元素的数据典范必须与字节码指令的序列严酷婚配,在编译代码时,编译器会严酷保证这一点,在类加载的校验阶段也会再次考证这一点。在上面的iadd指令中,只能用于整型数的加法,它在实行时,最靠近栈顶的两个元素的数据典范必须为int型,不能出现其他数据典范利用iadd命令相加的情况。
一个方式挪用此外一个方式时,可以经过操纵数栈来举行方式参数的转达。固然在Java捏造机标准中,两个差别栈帧作为差别方式的捏造机栈的元素,是完全相互自力的。可是在大多Java捏造机的实现时,城市举行一些优化:两个差别方式的栈帧出现一部分堆叠。让下面栈帧的部分操纵数栈与上面栈帧的部分部分变量表堆叠在一路,这样做不单节省了一些内存空间,更严重的是在举行方式挪用时便可以间接共用一部分数据,不需要举行额外的参数复制和转达,以下图:
详细解析Java虚拟机的栈帧结构  游戏

接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
静态毗连(Dynamic Linking)

每个栈帧都包含一个指向运转经常量池中该栈帧所属方式的援用,持有这个援用是为了支持方式挪用进程中的静态毗连。
之前的《Class文件结构周全分解》中先容过,Class文件的常量池中存有大量的标记援用,这些标记援用一部分会在类加载阶段大要第一次利用的时候就被转化为间接援用(现实运转时内存结构中的进口地址),这类转化被称为静态分解。此外一部分将在每一次运转时代都转化为间接援用,这部分就称为静态毗连。关于这两个转化进程的具体进程,这里先卖个关子,后续的文章会具体先容。
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
方式返回地址

方式返回时大要需要在栈帧中保存一些信息,用来于规复挪用者(挪用当前方法的方式)的实行状态。一样平常来说,方式一般退出时,挪用者的步伐计数器的值便可以作为返回地址,栈帧中很大要会保存这个计数器值。而方式很是退出时,返回地址是要经过很是处置惩罚器表来肯定的,栈帧中就一样平常不会保存这部分信息。
方式返回的进程现实上同即是把当前栈帧出栈,大要实行的操纵有:规复挪用者的部分变量表和操纵数栈,把返回值(倘使有的话)压入挪用者栈帧的操纵数栈中,调解步伐计数器的值使其指向方式挪用指令背面的一条指令等等。
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
附加信息

在Java捏造机标准中,答应Java捏造机增加一些标准里没有描摹的信息到栈帧当中,比如:调试、性能收集关连的信息,这部分信息完全取决于具体的捏造机实现。一样平常会把静态毗连、方式返回地址和其他附加信息全数归为一类,称为栈帧信息。
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。
总结

栈帧是Java捏造机中的捏造机栈的底子元素,每一个方式从挪用起头至实行竣事的全部进程,都对应着一个栈帧在捏造机栈中从入栈到出栈的进程。栈帧存储了方式的部分变量表、操纵数栈、静态毗连和方式返回地址和其他附加信息。部分变量表用于寄存方式参数和方式内部界说的部分变量;各类字节码指令实行时,会对操纵数栈举行出栈和入栈的操纵;静态毗连是指向运转经常量池中该栈帧所属方式的援用;方式返回地址用于规复挪用当前方法的方式的实行状态。
接待关注微信公众号:万猫学社,每周一分享Java技夺目货。

免责声明:假如加害了您的权益,请联系站长,我们会实时删除侵权内容,感谢合作!

本帖子中包含更多资源

您需要 登录 才可以下载或查看,没有帐号?立即注册

x
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

Copyright © 2006-2014 妈妈网-中国妈妈第一,是怀孕、育儿、健康等知识交流传播首选平台 版权所有 法律顾问:高律师 客服电话:0791-88289918
技术支持:迪恩网络科技公司  Powered by Discuz! X3.2
快速回复 返回顶部 返回列表