jvm栈帧包含哪些内容
发布网友
发布时间:2022-04-25 16:32
我来回答
共1个回答
热心网友
时间:2023-10-18 06:47
当线程执行到某个方法时就会往方线程栈中压入一个帧,称为栈帧,栈帧中包含了方法的局部变量表、操作数栈、返回地址、动态连接等信息
局部变量表:
顾名思义就是用来存储java方法中的局部变量的,在编译期间就会分配方法局部变量表的最大容量,局部变量表以变量槽为单位,每个变量槽可以存储32位及32位以下的变量,具体大小根据变量实际占用内存而定,java的基本类型中除了long和double外其他类型都是32位以下,所以每个变量占用一个变量槽即可,而对于long和double类的变量,会占用两个变量槽,除了基本类型当然还有引用类型,引用类型变量长度JVM并没有明确定义。JVM通过索引的方式来访问变量表中的变量,索引从0开始。变量槽是可以重复使用的,当变量槽所存储的变量已经不在其作用域后,该变量槽就可以被其他变量占用
操作数栈:
用于在方法运行时可以存放以及获取操作数,其所需要的最大栈深度也是在编译期间定下的,在方法刚开始运行时,操作数栈是空的,在方法执行过程中会有各种操作指令往操作数栈中压入和获取内容,也就是出栈/入栈操作,比如一个加法指令对两个数据进行相加,运行到这里前会先将两个数据压入栈中,然后将这两个操作数取出相加;在实际情况中,方法的操作数栈之间并不完全独立,往往会公用部分空间,这样在方法调用时就不需要进行参数复制了
动态连接:
前面说了常量池中会存储方法的符号引用,而每个栈帧中都会存储一个引用,用于指向常量池中该方法对应的符号引用,字节码指令中方法的调用就以方法对应的符号引用为参数来进行,在类加载阶段的解析步骤中,部分符号引用会被解析为直接引用,称为静态解析,在方法的运行过程中,另一部分符号引用会被实时的解析为直接引用,称为动态连接。
被静态解析的条件:方法在运行前就有一个可确定的调用版本,其实也就是编译期就刻意确定改方法有没有可能通过继承或者其他方式被重写,在java中静态方法(与类型直接关联),私有方法(外部不可访问),构造方法,父类方法,final方法,这五种方法的符号引用可以被静态解析都不可能被重写,可以在运行前确定唯一的调用版本,满足被静态解析的条件,称为非虚方法。
方法返回地址:
方法的运行过程中,可能会正常退出,也可能会异常退出,不论是哪种退出方式,在退出后都会要保证其上层调用者可以知道方法退出的位置,以便于程序继续执行,方法的返回地址就是用于确定退出位置的。