欢迎访问 生活随笔!

生活随笔

当前位置: 首页 > 编程资源 > 编程问答 >内容正文

编程问答

java slot_LocalVariableTable之 Slot 复用

发布时间:2025/3/12 编程问答 31 豆豆
生活随笔 收集整理的这篇文章主要介绍了 java slot_LocalVariableTable之 Slot 复用 小编觉得挺不错的,现在分享给大家,帮大家做个参考.

LocalVariableTable中的 Slot, 是存在复用现象的,这个我早就知道,但是,不太清楚是如何复用的。

Java语言规范与JVM规范都没有对Java语言具体要如何使用JVM的局部变量slot做太多限制,只是规定了参数要从下标为0开始的局部变量区传递而已。作用域不重叠的局部变量之间是否一定要复用局部变量区的slot,这纯粹是实现细节——复用也可以,不复用也完全符合规范。所以这种事情只能针对某个具体实现来讨论。假如题主是用Oracle/Sun JDK或者OpenJDK,那么用JDK自带的javap工具来看看不同样子的源码生成怎样的字节码就可以感受到差别了。

在Oracle/Sun JDK与OpenJDK里的javac实现,分配局部变量slot的方式非常死板,纯粹看几个因素:

声明顺序:先到先得;

作用域:进入作用域时抢最靠前得坑,一离开作用域就放开这个坑,让后面的作用域的变量可以占坑;

类型:long与double占俩相邻slot,其它类型占一个slot。

我用的Java版本是Hotspot ,如下,也是有这样的现象的。

java version "1.8.0_131"

Java(TM) SE Runtime Environment (build 1.8.0_131-b11)

Java HotSpot(TM) 64-Bit Server VM (build 25.131-b11, mixed mode)

一个关键点是作用域,什么是java中变量的作用域?它范围是,从定义变量的那一行开始,到对应的代码块结束的那一行。那么什么是代码块呢? 包含它的花括号的整个部分就是 一个代码块。

看一个例子,如下的代码:

private static void test1() throwsIllegalAccessException, InvocationTargetException, NoSuchMethodException {for (int i = 0; i < 3; i++) {int ia = 1;long long1 = 2;int ib = 3;long long2 = 555;

System.out.println(" over = ");

}

ArrayList array=new ArrayList();

array.add(1);for (int i=0;i

System.out.println(array.get(i));

Integer ia=array.get(i);

Integer ib=array.get(i);

System.out.println(ia);

}//int i = ia + ib;

}

javap得到的字节码是:

LocalVariableTable:

Start Length Slot Name Signature9 20 1 ia I13 16 2 long1 J16 13 4ib I21 8 5long2 J2 33 0i I82 16 2 ia Ljava/lang/Integer;91 7 3 ib Ljava/lang/Integer;54 50 1i I43 62 0 array Ljava/util/ArrayList;

Slot 值出现了重复的0,1,2... ,可见,Slot就是出现了复用。Slot的占用是按照变量在源码出现的顺序来的。 不过,奇怪的是,从上面的信息看来,Slot并不是按字节码信息LocalVariableTable表的顺序来的,Start,Length,Name,Signature都不是的。 ia占用1个slot,long1是2个(尽管long1的起始的slot还是2,但是我们从ib 的起始slot可以推测),long2 起始的slot是5,那么它占用了几个slot呢?从上面的字节码信息,我们并看不出上面东西呢,我们只能根据经验推测, 经验就是

long与double占俩相邻slot,其它类型占一个slot

如果非要看到long2 占用了几个slot,那么就需要再在其对应的作用域中long2 后面创建另外的变量,那么然后就可以通过它后面的变量的起始slot 推测了。

另外,我测试的时候,发现如果变量定义的位置是作用域最后一行的话,也就是说如果定义了变量,后面没有其他代码了,那么它是不会出现在LocalVariableTable表中的。为什么会这样?我想是因为这个时候它就完全无用了吧。如果要让它出现在LocalVariableTable表中,那么只要在其后面随便写点什么代码就好了!

需要注意的是,如果我们的方法,整个就一个作用域,是不会出现slot复用的,因为无法复用啊,一个方法什么情况会出现多个作用域呢? 其实很简单,一个while循环,或者for,或者if.. else,或者switch等等, 还有就是单单一个 花括号 包围也可以。

参考:

https://www.zhihu.com/question/41694588

总结

以上是生活随笔为你收集整理的java slot_LocalVariableTable之 Slot 复用的全部内容,希望文章能够帮你解决所遇到的问题。

如果觉得生活随笔网站内容还不错,欢迎将生活随笔推荐给好友。