JVM知识(三)---类的执行机制(上)

JVM完成类的加载并产生Class对象以后,就可以执行Class对象的静态方法或者实例化对象调用其方法。JVM在源码编译阶段将源码编译为JVM字节码,JVM字节码是一种中间代码,JVM会在运行期执行该中间代码,这种方式成为字节码的解释执行方式。
字节码的解释执行:
如下我们写出这样一个简单的类文件:

public class Demo {
	
public void execute() {
		Teacher.teach();
		Teacher teacher = new Teacher();
		teacher.run();
		People student = new Student();
		student.run();
	}
}

interface People {
	public int run();
}

class Teacher {
	public static int teach() {
		return 1 + 2;
	}
	public int run () {
		return 1+2;
	}
}

class Student implements People {
	public int run () {
		return 1 + 2;
	}
}


使用命令javac Demo.java编译上面的类,然后使用javap -c Demo查看该类方法execute方法生成的字节码文件如下:

public void execute();
  Code:
   0:   invokestatic    #2; //Method Teacher.teach:()I
   3:   pop
   4:   new     #3; //class Teacher
   7:   dup
   8:   invokespecial   #4; //Method Teacher."<init>":()V
   11:  astore_1
   12:  aload_1
   13:  invokevirtual   #5; //Method Teacher.run:()I
   16:  pop
   17:  new     #6; //class Student
   20:  dup
   21:  invokespecial   #7; //Method Student."<init>":()V
   24:  astore_2
   25:  aload_2
   26:  invokeinterface #8,  1; //InterfaceMethod People.run:()I
   31:  pop
   32:  return

}
JVM采用四种指令来执行不同的方法调用:invokestatic调用static方法,invokevirtual调用对象实例方法,invokeinteface调用的是接口方法,invokespecial调用的是private方法和编译源码后生成的init方法,如构造方法。

SUN JDK基于stack的体系结构来执行字节码,基于stack能是代码更加紧凑,体积更小。stack的系统结构如下图:


线程在创建后都会产生pc registers和stack;pc存放了下一条将要执行的指令在方法内的偏移量;stack中存放了StackFrame,每个方法每次调用都会产生StackFrame,StackFrame又主要分为局部变量区和操作数栈,局部变量区主要存放方法中的局部变量和参数,操作数栈主要存放方法在执行过程中产生的中间变量;下面我们具体来看一段代码的执行指令:代码很简单,如下:

public class Demo {
	public static void execute() {
		int a = 1;
		int b = 2;
		int c = (a + b) * 4;  
	}
}
以下为该类的完成字节码:

public class Demo extends java.lang.Object{
public Demo();
  Code:
   0:   aload_0
   1:   invokespecial   #1; //Method java/lang/Object."<init>":()V
   4:   return

public static void execute();
  Code:
   0:   iconst_1           // 将类型为int,值为1的常量放入操作数栈中
   1:   istore_0	   //将操作数栈中栈顶的值放入局部变量区
   2:   iconst_2	   //将类型为int,值为2的常量放入操作数栈中
   3:   istore_1	   //将操作数栈栈顶的值放入局部变量区
   4:   iload_0		   //装载局部变量区的第一个值到操作数栈
   5:   iload_1		   //装载局部变量区的第二个值到操作数栈
   6:   iadd		   //执行int整数的加法操作,并将结果存入操作数栈中
   7:   iconst_4	   //将类型为int,值为4的常量放入操作数栈中
   8:   imul		   //执行乘法操作,并将结果存入操作数栈中
   9:   istore_2	   //将操作数栈中栈顶的值存入局部变量区
   10:  return		   //返回

}


我们主要看该execute方法下的code,指令的解释详见指令后面的注释。

     

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值