JVM 之 虚拟机字节码执行引擎及动态语言支持

运行时栈帧结构

栈帧:

局部变量表:
一组变量值存储空间。用于存放方法参数和方法内部定义的局部变量。 在Java程序被编译为Class文件时,就在方法的Code属性的max_locals数据项中 确定了方法所需要分配的最大局部变量表的容量。
单位:slot
存储数据类型和引用。
大小根据操作系统确定。32bit系统为32bit,64bit系统为64bit。存储数据类型时,如果小于32位使用一个slot;如果大于32位使用两个slot。

  1. 32位数据类型:
  2. boolean,byte,char,short,int,float,refrence,returnAddress
  3. 64位数据类型:
  4. longdouble
  5. 复用:当一个变量的PC寄存器的值大于slot的作用域的时候,Slot是可以复用的。
  6. 代码优化:
  7. 局部变量没有初始值,声明时要赋值。
  8. 对象使用完之后指向为null,方便垃圾回收。
  9. 操作数栈:
  10. 运算的地方。
  11. 一个以字长为单位的数组。通过压栈和出栈来访问。
  12. 动态链接
  13. 静态链接:加载过程中间链接接转为直接链接
  14. 动态链接:每次运行期间都会转化为直接链接
  15. 返回地址
  16. 方法调用时记录调用方法地址,方法执行完毕之后跳回到所调方法位置。
  17. 附加信息
  18. 虚拟机规范允许具体虚拟机添加一些规范中没有的信息到栈帧中。这些信息取决于虚拟机的实现。

方法调用

  1. 方法调用并不等于方法的执行,方法调用阶段的唯一任务就是确定被调用方法的版本。
  • 解析调用
    方法在编译的时候就确定了,方法的调用版本在运行之前不变的。(静态方法,构造器方法,私有方法,final方法)涉及到的指令:invokespecial,invokestatic。
  • 分派调用

    • 静态分派调用
      在编译器时期就确定方法的版本。如果存在函数重载,那么在调用是按照参数类型匹配最接近的方法。
    • 动态分派调用
      1.找到操作数栈顶的第一个元素所指向的对象的实际类型
      2.如果在实际类型中找到与常量中的描述符和简单名称都相符的方法,则进行访问权限校验,如果通过则直接返回这个方法的直接引用,查找过程结束,如果不通过,抛出异常。

动态语言支持

  1. public class ScriptTest {
  2. public static void main(String[] args) throws ScriptException {
  3. ScriptEngineManager sem = new ScriptEngineManager();
  4. ScriptEngine se = sem.getEngineByName("JavaScript");
  5. Object obj = se.eval("function add(a,b){ return a+b;} add(2,3)");
  6. System.out.println(obj);
  7. }
  8. }

发表评论

表情:
评论列表 (有 0 条评论,23人围观)

还没有评论,来说两句吧...

相关阅读

    相关 虚拟字节执行引擎

    > 不同虚拟机实现中,执行引擎在执行字节码得时候通常会有解释执行和编译执行两种选择,也可能两者兼具,还有可能同时包含几个不同级别得即使编译器一起工作得执行引擎,但是所有 Jav

    相关 虚拟字节执行引擎

    在前面的几篇文章里,从Java虚拟机内存结构开始,经历了虚拟机垃圾收集机制、Class类文件结构到后来的虚拟机类加载机制,一步步的进入到了Java虚拟机即Java底层的世界。在

    相关 JVM虚拟字节执行引擎

    执行引擎是Java虚拟机最为核心的组成部分之一. 虚拟机是一个相对于物理机的概念, 两种及其都有代码执行能力, 其区别是物理机的执行引擎是直接建立在处理器, 硬件, 指令集和操