第八章虚拟机字节码执行引擎

局部变量表

A、类变量有两次赋初始值的过程:

1、一次在准备阶段赋予系统初始值;

2、另一次是在初始化阶段,赋予程序员定义的初始值。

B、局部变量没有这样的富裕默认值的机制,局部变量必须赋值后才能使用。

操作数栈

8.2.3动态连接

指向运行时常量池中该栈帧所属方法的引用。

8.2.4方法返回地址

1、正常完成出口

2、异常完成出口

8.2.5附加信息

8.3方法调用

8.3.1解析

在java语言中,符合"编译期可知,运行期不可变"这个要求的方法主要有静态方法和私有方法。前者直接与类关联,后者在外部不可访问。

只要能被invokestatic和invokespecial指令调用的方法都可以在解析阶段确定为一的调用版本。符合这个条件的有静态方法、私有方法、实例构造器和父类方法四类,这类方法可以称为非虚方法。

8.3.2分派

Java具备面向对象的三个基本特征:继承、封装和多态,分派调用解释了多态特征在java中是如何实现的。

  1. 静态分派
package com.jvmstudy.chapter8; 
 
public class StaticDispath { 
 
   static class Human { 
 
   } 
 
   static class Man extends Human { 
 
   } 
 
   static class Woman extends Human { 
 
   } 
 
   public void sayHello(Human guy) { 
      System.out.println("Hello guy!"); 
   } 
 
   public void sayHello(Woman guy) { 
      System.out.println("Hello Woman!"); 
   } 
 
   public static void main(String[] args) { 
      Human man = new Human(); 
      Human woman = new Woman(); 
      StaticDispath p = new StaticDispath(); 
      p.sayHello(man); 
      p.sayHello(woman); 
   } 
 
} 
  1.   Human woman = new Woman();

上面的Human称为变量的静态类型,Woman称为其实际类型,javac根据参数的静态类型决定使用哪个版本.

public static void main(java.lang.String[]); 
  flags: ACC_PUBLIC, ACC_STATIC Code: 
    stack=2, locals=4, args_size=1 
       0: new #38 // class com/jvmstudy/chapter8/StaticDispath$Human 
       3: dup 
       4: invokespecial #40 // Method com/jvmstudy/chapter8/StaticDispath$Human."<init>":()V 
       7: astore_1 
       8: new #41 // class com/jvmstudy/chapter8/StaticDispath$Woman 
      11: dup 
      12: invokespecial #43 // Method com/jvmstudy/chapter8/StaticDispath$Woman."<init>":()V 
      15: astore_2 
      16: new #1 // class com/jvmstudy/chapter8/StaticDispath 
      19: dup 
      20: invokespecial #44 // Method "<init>":()V 
      23: astore_3 
      24: aload_3 
      25: aload_1 
      26: invokevirtual #45 // Method sayHello:(Lcom/jvmstudy/chapter8/StaticDispath$Human;)V 
      29: aload_3 
      30: aload_2 
      31: invokevirtual #45 // Method sayHello:(Lcom/jvmstudy/chapter8/StaticDispath$Human;)V 
      34: return 

  26行和31行为其字节码代码

  1. 动态分派

    Invokevirtual指令的解析过程:

    1. 找到操作数栈顶的第一个元素所指向的实际类型,记作C。
    2. 如果在类C中找到与常量的描述符和简单名称都符合的方法,则进行访问权限校验,如果通过泽返回这个方法的直接引用,查找过程结束,不通过则返回非法访问错误
    3. 否则从下向上依次对C的各个父类进行第2步的搜索和验证
    4. 如何找不到合适的方法则抛出java.lang.AbstractMethodError。
  2. 单分派与多分派
  3. 虚拟机动态分派的实现机制

    动态分派非常频繁,最常用的稳定优化手段

    为类在方法区建立一个虚方法表Vtable

    接口也会有Itable

8.4基于栈的字节码解释执行引擎

8.4.2基于栈的指令集与基于寄存器的指令集

基于栈的指令集:零地址指令,它依赖操作数栈进行操作.

基于寄存器的指令集架构:依赖寄存器进行工作,依赖于具体硬件.

原文地址:https://www.cnblogs.com/xqlcrystal/p/3067214.html