面试题:局部变量表用来干嘛的?

定义如下的方法

  1. public class Test2 {
  2. public int test2(int n){
  3. int a = 1000;
  4. long b = 2000;
  5. int c=3000;
  6. return a;
  7. }
  8. }

一句话讲清楚:它用来存储方法参数、方法体内的变量的
局部变量表的生命周期:随线程而生,随线程而灭。

如何查看这张表?
在class文件的字节码里面

为什么通过字节码文件,就能查看到局部变量表?
因为这张表在编译的时候,就建好了,就像我们操作数据库一样,要先把表建好,程序才能对表进行读写操作。

字节码指令地址如何和源码关联?
通过行号表
image.png

如何查看局部变量表?
image.png

局部变量表存储了哪些数据类型?

思考:
数据库每个字段都要给他设置数据类型,例如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个槽位
image.png
索引名直接从3到5了,因为long类型占用了2个slot

图解分析:局部变量表的对象引用原理

查看下面的类

  1. public class Test3 {
  2. static final String KEY = "oyb";
  3. private String name;
  4. public void setName(String name) {
  5. this.name = name;
  6. }
  7. public static void main(String[] args) {
  8. Test3 referece=new Test3();
  9. int temp=0;
  10. referece.setName("abc");
  11. }
  12. }

image.png
以上图,说明了对象引用的数据类型占用了一个slot槽位
image.png
这个reference对象引用,需要涉及3个区域:栈、堆、方法区
栈帧:本地变量表,存放了refrence对象引用。
堆:存放了对象实例Test2的数据,例如对象成员变量name的值=abc。
方法区:存放对象的数据类型(对象类型、父类、实现接口、方法、常量等等)的地址信息。例如KEY的值

图解分析:操作数栈的压栈与出栈

什么是操作数栈

操作数栈主要用于计算过程中的临时数据存储,即计算过程中变量的临时存储空间。
来一种简单抽象的比喻:局部变量表类似磁盘、操作数栈类似内存。
具体的操作流程是:
每次执行一个方法,方法内部的字节码指令,就会对栈进行写数据(入栈push)或取数据(出栈pop)

  1. public class Test1 {
  2. public void test(){
  3. int a = 1000;
  4. int b = 2000;
  5. int c=a+b;
  6. }
  7. }

操作数栈有什么特点

  1. 当一个方法开始执行时,就会创建一个新的栈帧,同时栈帧就包含了一个空的操作数栈。
  2. 栈的数据结构一般采用数组或者链表来实现,栈的元素大小是32bit,如果是long类型的就占2个元素。

它的存储空间和局部变量表一样都是32bit,但是区别是,局部变量表时通过索引来访问;
而操作数栈是通过压栈和出栈来访问。例如 某个指令把一个值压入操作数栈,稍后另一个指令就可以弹出这个值来使用。