【java】java 局部变量表中的槽是可以重用的

x33g5p2x  于2022-03-22 转载在 Java  
字(1.5k)|赞(0)|评价(0)|浏览(233)

1.概述

2.局部变量表

局部变量表(Local Variables Table)用来保存方法中的局部变量,以及方法参数。当 Java 源代码文件被编译成 class 文件的时候,局部变量表的最大容量就已经确定了

我们来看这样一段代码。

public class LocalVaraiablesTable {
    private void write(int age) {
        String name = "沉默王二";
    }
}

write() 方法有一个参数 age,一个局部变量 name。

然后用 Intellij IDEA 的 jclasslib 查看一下编译后的字节码文件 LocalVaraiablesTable.class。可以看到 write() 方法的 Code 属性中,Maximum local variables(局部变量表的最大容量)的值为 3。

按理说,局部变量表的最大容量应该为 2 才对,一个 age,一个 name,为什么是 3 呢?

当一个成员方法(非静态方法)被调用时,第 0 个变量其实是调用这个成员方法的对象引用,也就是那个大名鼎鼎的 this。调用方法 write(18),实际上是调用 write(this, 18)

点开 Code 属性,查看 LocalVaraiableTable 就可以看到详细的信息了。

第 0 个是 this,类型为 LocalVaraiablesTable 对象;第 1 个是方法参数 age,类型为整形 int;第 2 个是方法内部的局部变量 name,类型为字符串 String。

当然了,局部变量表的大小并不是方法中所有局部变量的数量之和,它与变量的类型和变量的作用域有关。当一个局部变量的作用域结束了,它占用的局部变量表中的位置就被接下来的局部变量取代了。

来看下面这段代码。

public static void method() {
    // ①
    if (true) {
        // ②
        String name = "沉默王二";
    }
    // ③
    if(true) {
        // ④
        int age = 18;
    }
    // ⑤
}
  • method() 方法的局部变量表大小为 1,因为是静态方法,所以不需要添加 this 作为局部变量表的第一个元素;
  • ②的时候局部变量有一个 name,局部变量表的大小变为 1;
  • ③的时候 name 变量的作用域结束;
  • ④的时候局部变量有一个 age,局部变量表的大小为 1;
  • ⑤的时候局 age 变量的作用域结束;
    关于局部变量的作用域,《Effective Java》 中的第 57 条建议:

将局部变量的作用域最小化,可以增强代码的可读性和可维护性,并降低出错的可能性。

在此,我还有一点要提醒大家。为了尽可能节省栈帧耗用的内存空间,局部变量表中的槽是可以重用的,就像 method() 方法演示的那样,这就意味着,合理的作用域有助于提高程序的性能。

局部变量表的容量以槽(slot)为最小单位,一个槽可以容纳一个 32 位的数据类型(比如说 int,当然了,《Java 虚拟机规范》中没有明确指出一个槽应该占用的内存空间大小,但我认为这样更容易理解),像 float 和 double 这种明确占用 64 位的数据类型会占用两个紧挨着的槽。

来看下面的代码。

public void solt() {
    double d = 1.0;
    int i = 1;
}

用 jclasslib 可以查看到,solt() 方法的 Maximum local variables 的值为 4。

为什么等于 4 呢?带上 this 也就 3 个呀?

查看 LocalVaraiableTable 就明白了,变量 i 的下标为 3,也就意味着变量 d 占了两个槽。

此时知识联动了,赞 【Java】String 以及 StringTable 骨灰级 细节讲解 源码讲解 这里面有String的槽位。

M.参考

转载:携程面试官竟然问我 Java 虚拟机栈

相关文章

微信公众号

最新文章

更多