long、double类型在局部变量表中需要占用2个槽位
其他类型如int、引用类型需要占用1个槽位
非static的成员方法的第一个局部变量都是this引用
以上一节的例子为例
一共占用5个槽位,其中
D(double)类型的arg1占用2 槽位,其余各占用1个槽位。
局部变量表中的槽位是可以复用的
如果一个局部变量过了其作用范围,那么在其作用范围后申明的新的局部变量,就有可能复用过期的局部变量的槽位,从而达到节省资源的目的。
以如下代码为例
Java Code
1 | package com.test.a; |
method1()的局部变量表占用3个槽位,其中this占用1个,a、b各占用一个
method2的局部变量表占用2个槽位,虽然也拥有this、a、b 3个局部变量,但是b复用了a的槽位,他们都占用的第1个槽位
同理,method3的局部变量表占用3个槽位,c、d分别复用了循环语句中的a、b的槽位
在执行阶段,.class文件中的局部变量表会被使用到栈帧的局部变量表中
后面会讲到,被栈帧的局部变量表直接或间接引用到的对象,在垃圾回收时是不会被回收的
槽位复用也会影响到垃圾回收,以如下代码为例,运行时使用-XX:+PrintGC参数
Java Code
1 | package com.test.b; |
在method1()中,在垃圾回收前先将a置null,使byte数组失去被引用,故可以顺利回收byte数组
在method2()中,虽然a已经离开了作用范围,但是a仍然存在于栈帧的局部变量表中,并且引用byte数组,故byte数组还不能被回收
在method3()中,局部变量b会复用a的槽位
在垃圾回收前,申明了变量b来复用a的槽位,此时栈帧的局部变量表中没有引用byte数组,故能够顺利回收byte数组