JVM之一:操作数栈和局部变量表
Posted 小猪快跑22
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了JVM之一:操作数栈和局部变量表相关的知识,希望对你有一定的参考价值。
每个方法被执行的时候,JVM 都会在虚拟机栈中创建一个栈帧,栈帧是什么呢?
一、栈帧
栈帧(Stack Frame)是用于支持虚拟机进行方法调用和方法执行的数据结构,每一个线程在执行某个方法时,都会为这个方法创建一个栈帧。
我们可以这样理解:一个线程包含多个栈帧,而每个栈帧内部包含局部变量表、操作数栈、动态连接、返回地址等。
这里来说下 局部变量表的最大长度和操作数栈的最大深度。
- 当一个方法开始执行的时候操作数栈是空的。
- 操作数栈的最大深度在编译期就决定了。
- 栈中的任何一个元素可以是任意的Java 类型
注意:
32 bit 占一个单位深度(slot)
64 bit 占2个单位深度(slot) 即 long double 类型占2个slot
下面举例说明:
public void add(int a, int b)
int sum = a + b;
操作指令如下:
public void add(int, int);
descriptor: (II)V
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=3
0: iload_1
1: iload_2
2: iadd
3: istore_3
4: return
LineNumberTable:
line 6: 0
line 7: 4
解释下上面的语句。
当add方法编译开始的时候:局部变量表里面的元素是 [this, int, int] 。因为add方法是普通方法而不是 static 方法,所以索引为0的位置存放的是当前类的对象;
静态方法属于类而不是对象,所以不需要。
iload_1 :把局部变量表索引为1的(参数a的值)压入栈:[int] — int 型数据所以用 iload,如果是对象的引用则用 aload
iload_2 :把局部变量表索引为2的(参数b的值)压入栈:[int, int]
iadd :把栈上的最上面2个数据先出栈,然后相加,得到的结果再次压入栈:[int] 存的是相加的结果
istore_3 :把栈顶的数据放到局部变量表索引为3的位置 [this, int, int,int]
return : 方法执行完,退出
如上,可以看到 栈的最大深度为2,局部变量表的最大长度为4,符合上面的 stack=2, locals=4。
当我们把 add 方法参数类型改为 long ,如下:
public void add(long a, long b)
long sum = a + b;
如下:
public void add(long, long);
descriptor: (JJ)V
flags: ACC_PUBLIC
Code:
stack=4, locals=7, args_size=3
0: lload_1
1: lload_3
2: ladd
3: lstore 5
5: return
LineNumberTable:
line 6: 0
line 7: 5
为是 long 类型,占2个slot,所以开始的局部变量表如下:[this, long, top, long, top]
lload_1 : 操作栈 [long, top]
lload_3 : 操作栈 [long, top, long, top]
ladd : 出栈后相加后压入栈 [long, top]
lstore : 将栈顶的求和的结果存入局部变量表:[this, long, top, long, top, long, top]
所以 栈最大深度为4,局部变量表的最大长度为 7,符合上面的 stack=4, locals=7
二、如果方法有返回值的话,其返回值将会被压入当前栈帧的操作数栈中。
public int add(int a, int b)
int sum = a + b;
return sum;
public int add(int, int);
descriptor: (II)I
flags: ACC_PUBLIC
Code:
stack=2, locals=4, args_size=3
0: iload_1
1: iload_2
2: iadd
3: istore_3
4: iload_3 // 多了一步将局部变量表索引值为3的数组压入操作数栈
5: ireturn // 因为这次 add 有返回值,且返回值为 int 类型,所以指令为 ireturn
LineNumberTable:
line 6: 0
line 7: 4
以上是关于JVM之一:操作数栈和局部变量表的主要内容,如果未能解决你的问题,请参考以下文章