面试题:局部变量表用来干嘛的?
定义如下的方法
public class Test2 {
public int test2(int n){
int a = 1000;
long b = 2000;
int c=3000;
return a;
}
}
一句话讲清楚:它用来存储方法参数、方法体内的变量的
局部变量表的生命周期:随线程而生,随线程而灭。
如何查看这张表?
在class文件的字节码里面
为什么通过字节码文件,就能查看到局部变量表?
因为这张表在编译的时候,就建好了,就像我们操作数据库一样,要先把表建好,程序才能对表进行读写操作。
字节码指令地址如何和源码关联?
通过行号表
局部变量表存储了哪些数据类型?
思考:
数据库每个字段都要给他设置数据类型,例如int, 那局部变量表的数据类型是什么呢?
局部变量表的数据类型是slot(变量槽)、而且只有一个数据类型,不像数据库那么多类型。
那这个slot槽有多大?
一个slot位是32bit
java的数据类型分为2种:原始类型和引用类型
原始类型:分为8中基本类型(byte short int long float double char boolean)和returnAddress类型
引用类型:包括对象引用 和 数组引用
思考:一个槽位32bit如何装下java的各种数据类型??
小于32bit装一个slot,大于32bit 装2个槽位。
byte short int float char boolean 装1个槽位
long double 装2个槽位
索引名直接从3到5了,因为long类型占用了2个slot
图解分析:局部变量表的对象引用原理
查看下面的类
public class Test3 {
static final String KEY = "oyb";
private String name;
public void setName(String name) {
this.name = name;
}
public static void main(String[] args) {
Test3 referece=new Test3();
int temp=0;
referece.setName("abc");
}
}
以上图,说明了对象引用的数据类型占用了一个slot槽位
这个reference对象引用,需要涉及3个区域:栈、堆、方法区
栈帧:本地变量表,存放了refrence对象引用。
堆:存放了对象实例Test2的数据,例如对象成员变量name的值=abc。
方法区:存放对象的数据类型(对象类型、父类、实现接口、方法、常量等等)的地址信息。例如KEY的值
图解分析:操作数栈的压栈与出栈
什么是操作数栈
操作数栈主要用于计算过程中的临时数据存储,即计算过程中变量的临时存储空间。
来一种简单抽象的比喻:局部变量表类似磁盘、操作数栈类似内存。
具体的操作流程是:
每次执行一个方法,方法内部的字节码指令,就会对栈进行写数据(入栈push)或取数据(出栈pop)
public class Test1 {
public void test(){
int a = 1000;
int b = 2000;
int c=a+b;
}
}
操作数栈有什么特点
- 当一个方法开始执行时,就会创建一个新的栈帧,同时栈帧就包含了一个空的操作数栈。
- 栈的数据结构一般采用数组或者链表来实现,栈的元素大小是32bit,如果是long类型的就占2个元素。
它的存储空间和局部变量表一样都是32bit,但是区别是,局部变量表时通过索引来访问;
而操作数栈是通过压栈和出栈来访问。例如 某个指令把一个值压入操作数栈,稍后另一个指令就可以弹出这个值来使用。