什么是栈帧。
当一个方法被执行的时候,虚拟机会生成一个 栈帧,一个栈帧在虚拟机上入栈到出栈的调用,等于这个方法执行。线程独享的。 在活动的线程中,只有位于栈顶的栈帧是有效的。栈帧结构如下。
运行时的栈帧结构: 局部变量表,方法返回值,动态连接,操作栈。
什么是 局部变量表?
我们的方法有参数和 自己定义的局部变量,局部变量表 就是来存储这些数据的一个结构。并且一个 class被加载好后,其code属性的max_local的值已经确定。即 局部变量表的大小已经确定。
在局部变量表里存放,【char byte long int folat short returnaddress reference 】 等结构。 跟java 8 的基础类型 相似。 没有 long 和double。
其中存放单位是变量槽(Slot)。 32 位的数据类型占1个 单位slot。64位的占两个。
reference类型虚拟机规范没有明确说明它的长度,但一般来说,虚拟机实现至少都应当能从此引用中直接或者间接地查找到对象在Java堆中的起始地址索引和方法区中的对象类型数据。
returnAddress类型是为字节码指令jsr、jsr_w和ret服务的,它指向了一条字节码指令的地址。
什么操作数栈。
java 虚拟机的解释执行引擎被称为“ 基于栈的执行引擎”,这里的栈值得就是 操作数栈。
操作数栈operand stack。当方法刚开始的时候,操作数栈是空的,当党法开始执行的时候,会有各种字节码指令往操作数栈中写入或提取内容,这个过程称为出栈、入栈操作。
操作数栈数栈是有深度的。在class 被编译的时候,深度值在code里的max_stack里。操作数栈的数度不会超过这个值。
如下图,
另外,虽然说每个虚拟机栈元素是相互独立的,但多数虚拟机会有一些优化,让线面的操作数栈和上面的操作数栈有共享区域,这样就少了额外的赋值传递。
code 属性有相应的操作数栈的执行顺序,当程序执行时,依次执行操作数,从局部变量表或者常量池堆变量进行进行入栈或出栈的操作。
什么是动态连接?
栈帧中包含着正在运行的常量池对对这个栈帧的引用。符号引用转直接引用,第一次就转化成功的,称为静态解析。另一部分在运行期转化为直接引用,称为动态引用。
什么是方法返回地址?
方法的返回只有遇到任意一个方法返回的字节码指令,或者是在只能高兴过程中出现了异常。
无论何种方法退出,都需要保证退出时,程序能够返回到方法的调用地址,程序才能继续执行,方法返回在栈帧中保存这些信息,用来恢复它的上层方法的执行状态。
很清楚的讲了符号引用和直接引用。
https://www.zhihu.com/question/30300585
方法调用
解析:
符号引用转直接引用
分派:
静态分派:主要是 静态方法、构造器、私有方法、父类方法。在类加载的时候就会把符号引用解析为直接引用。