微信网站开发视频教程,网络营销前景和现状分析,商品展示网站源码,上海外滩LocalVariableTable中的 Slot#xff0c; 是存在复用现象的#xff0c;这个我早就知道#xff0c;但是#xff0c;不太清楚是如何复用的。Java语言规范与JVM规范都没有对Java语言具体要如何使用JVM的局部变量slot做太多限制#xff0c;只是规定了参数要从下标为0开始的局部…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_131Java(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 arraynew ArrayList();array.add(1);for (int i0;iSystem.out.println(array.get(i));Integer iaarray.get(i);Integer ibarray.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表的顺序来的StartLengthNameSignature都不是的。 ia占用1个slotlong1是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