1.概述
执行引擎是jvm核心组成部分之一,建立在物理器,硬件和操作系统层面之上,引擎在执行代码时会有解释执行和编译执行两种选择,输入字节码文件,字节码解析输出结果.
2.栈帧
栈帧是用于支持虚拟机进行方法调用和执行方法的结构,是虚拟机运行时数据区中的虚拟机栈的栈元素,存储方法的局部局部变量,操作数栈,动态链接和方法返回地址等信息,对应着入栈和出栈的过程.
上面是栈帧的基本结构,在线程中的方法调用链中同时执行很多方法,但只有栈顶的栈帧才是有效的,称为当前栈帧,与这个帧关联的叫当前方法,而栈帧的结构中主要分为局部变量表,操作栈,动态链接和方法返回地址
3.局部变量表
Local Variable Table是一组变量存储空间,用于存放方法参数和方法内部定义的局部变量,当java去编译class文件时,方法的code属性中的max_locals数据项用于确定和分配局部变量表的大小容量,在局部变量表中容量以slot为最小单位,在32位中可以存放基本数据类型,但是reference中的引用通过直接或间接的查找java堆中的起始地址索引,或者直接找到对象所属数据类型在方法区中的存储信息。而在64位中,虚拟机会以高位对齐的方式分配两个连续的slot空间,而只有long和double处于64位空间中,所以java规定将读写分为2个32位的读写做法.由于局部变量是线程私有的数据,当在读写两个连续的slot空间中也不会造成数据安全问题,
虚拟机通过索引定位的方式使用局部变量表,范围是从0到局部变量表中slot的最大范围,在方法执行时,使用局部变量表完成参数值到参数变量传递过程中,如果执行的是实例方法,局部变量表中第0位索引中的solt将默认用于传递方法所属对象的引用,而通过"this"进行访问参数时,参数则按照表参数表排序排列,而局部变量表中的slot可以重用.
在参数赋值时,为对象手动赋NULL或者0可以保证字节码校验的准确性保证了类加载的有效性,但在JIT编译优化后会被清除,所以局部变量和类变量在默认值上存在着区别。
4.操作数栈
Operand Stack也被称为操作栈,是一个后入先出的表,最大深度也是Code属性中的mac_stacks中,数栈中每一个元素可以是任意的数据类型,32位的容量为1,64为2,当一个方法执行时,方法的数栈为空,在执行的过程中,作为出栈/入栈操作,而在两个栈帧作为虚拟机栈的元素是完全独立的.
5.动态连接
每一个栈帧包含着一个指向RCP中该栈帧所属方法的引用,为了支持调用过程中的方法调用,而将符号参数引用在类加载阶段在每一次运行期间直接引用则为动态连接,而在方法中在Class文件里面都是一个符号引用,在类加载解析阶段,会将一部分符号直接转换为直接引用,而解析在方法的调用中实现编译器的执行.
在java复合,编译器可知,运行期不可变的方法中,主要包含私有方法和静态方法.静态方法与类型直接关联,而私有不可访问,而jvm提供了5条方法调用字节码命令,
- invokestatic :调用静态方法
- invokespecial:调用实例构造器<init>方法
- invokevirtual: 调用所有虚方法
- invokeinterface: 调用接口方法
- invokedynamic: 动态解析限定符所引用方法