1.JVM變量槽Slot的理解
1.Slot
是局部變量表中最基本的存儲單元。
2.參數值的存放總是從局部變量表數組的index 0
開始,到數組的-1
的索引結束。
3.局部變量表中存放的是局部變量,包括8
種基本數據類型,引用數據類型,returnAddress
類型的變量。
4.32
位以內的數據佔用一個Slot
(包括returnAddress
類型,引用數據類型),64
位類型的(long
, double
)佔用兩個Slot
。
5.JVM
會爲局部變量表中的每一個Slot
分配一個訪問索引,通過這個索引來訪問局部變量。
6.當一個實例方法(非靜態方法)被調用的時候,它的方法參數和方法體內部定義的局部變量將會按照順序被複制到局部變量的每一個Slot
上。
7.如果需要訪問局部變量表中的一個64
位的局部變量值時,只需要使用前一個索引即可。(例如:訪問long
或double
類型的變量)
8.如果當前棧幀是由構造方法或者實例方法創建的,那麼該對象引用this
將會存放在index
爲0
的slot
處,其餘的參數按照參數表的順序繼續進行存儲。
理解Slot的例子演示:
package jvn;
import java.util.Date;
public class LocalVariablesTest {
private int count = 0;
public static void main(String[] args) {
LocalVariablesTest test = new LocalVariablesTest();
int num = 10;
test.test1();
}
//練習:
public static void testStatic(){
LocalVariablesTest test = new LocalVariablesTest();
Date date = new Date();
int count = 10;
System.out.println(count);
//因爲this變量不存在於當前方法的局部變量表中!!
// System.out.println(this.count);
}
//關於Slot的使用的理解
public LocalVariablesTest(){
this.count = 1;
}
public void test1() {
Date date = new Date();
String name1 = "atguigu.com";
test2(date, name1);
System.out.println(date + name1);
}
public String test2(Date dateP, String name2) {
dateP = null;
name2 = "songhongkang";
double weight = 130.5;//佔據兩個slot
char gender = '男';
return dateP + name2;
}
public void test3() {
this.count++;
}
}
編譯上面的java代碼,使用Jclasslib
打開生成的LocalVariablesTest.class
文件。關於JClasslib的使用參考:https://blog.csdn.net/u011069294/article/details/107079185
1.選中test1
方法:
從Name
列可以看到總共存儲了3個局部變量,this,date
,以及name1
。驗證了上面講到的,當一個方法是構造方法或者實例方法的時候,對象引用this
會被存儲到局部變量表的index=0的位置,然後其他的局部變量按順序存儲。
從Index
列可以看出,每個變量的索引的起始位置以及所佔的slot
數目。this
索引起始位置是0,它下一個變量data
索引起始位置是1,說明this
佔了一個Solt
。同理可以看出data也佔了一個Slot
。
2.選中test2
方法:
同樣可以看出第一個變量存儲的是this
。後面的變量按順序存儲。
特別需要注意的一點的是變量weight
是一個Double
數據類型,索引起始位置是3
,結束位置是5
,所以它佔了兩個Slot
。
3.選中<init>
方法
可以看到構造方法只存儲了一個this
。
9.Slot
是可以重複利用的。如果一個局部變量出了其作用域,那麼在其作用域之後聲明的新的局部變量就很可能會重複使用過期的局部變量的槽位。
SLot
重複利用的例子:
package jvn;
public class LocalVariablesTest {
public void test4() {
int a = 0;
{
int b = 0;
b = a + 1;
}
//變量c使用之前已經銷燬的變量b佔據的slot的位置
int c = a + 1;
}
}
同樣使用Jclasslib
打開LocalVariablesTest.class
。
1.選中test4
方法。
可以看出,變量c
和變量b
的索引起始地址都是2
,所以變量c
複用了變量b
的Slot
。
更多JVM文章請參考我的JVM專欄:https://blog.csdn.net/u011069294/category_10113093.html