jvm-java虚拟机栈详解

虚拟机栈存储内容

在这里插入图片描述

栈帧

每个栈帧对应一个被调用的方法,可理解为一个方法的运行空间。

Local Variables 局部变量表

方法中定义的局部变量及方法的参数
局部变量表中的变量不可直接使用,如需使用,必须通过相关指令将其加载至操作数栈中作为操作数使用。
局部变量表在编译器就已经确定大小了,因为局部变量的类型和个数在编译器就已确定。

Operand Stacks 操作数栈

以入栈和出栈方式存储操作数

Dynamic Linking 动态链接

每个栈帧都包含一个执行运行时常量池中该栈帧所属方法的引用。
持有这个引用是为了支持方法调用过程中的动态连接(Dynamic Linking)

Invocation/Completion 方法返回地址

当一个方法开始执行后,只有两种方式可以退出,
一种是遇到方法返回的字节码指令;
一种是遇见异常,并且这个异常没有在方法体内得到处理。

例子

class Person{
	private String name="Jack";
	private int age;
	private final double salary=100;
	private static String address;
	private final static String hobby="Programming";
	public void say(){
		System.out.println("person say...");
	}
	public static int calc(int op1,int op2){
		op1=3;
		int result=op1+op2;
		return result;
	}
	public static void order(){
		
	}
	public static void main(String[] args){
		calc(1,2);
		order();
	}
}

对java文件进行分析

  1. 对Person.java 编译

javac Person.java 生成Person.class

  1. 对Person.class进行反编译

javap -c Person.class

  1. 截图如下
    在这里插入图片描述

对calc()方法分析

https://docs.oracle.com/javase/specs/jvms/se8/html/jvms-6.html#jvms-6.5.iconst_i

public static int calc(int op1,int op2){
		op1=3;
		int result=op1+op2;
		return result;
	}

calc()中的局部变量为op1,op2,result 对应到局部变量表中
在这里插入图片描述

public static int calc(int, int);
   Code:
      0: iconst_3    //Push int constant               把int常量值3push到操作数栈中
      1: istore_0    //Store int into local variable   把3存储到局部变量0中-->弹出操作数栈赋值给局部变量0
      2: iload_0     //Load int from local variable    从局部变量表里加载局部变量0到操作数栈
      3: iload_1	 //Load int from local variable    从局部变量表里加载局部变量1到操作数栈
      4: iadd	 	 //Add int						   将上述两个值弹出栈进行相加,结果push回操作数栈
      5: istore_2    //Store int into local variable    将栈顶int值保存到局部变量2中
      6: iload_2     //Load int from local variable     从局部变量表里加载局部变量2到操作数栈  
      7: ireturn   	 //Return int from method            从方法中返回int类型的数据
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章