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 复用的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: android.app.activity
- 下一篇: Python-OpenCV 笔记8 --