1. 程式人生 > >棧,堆,方法區之間的引用關係

棧,堆,方法區之間的引用關係

序言

在jvm的記憶體模型中主要包括包括 虛擬機器棧,堆,方法區,pc計數器,native棧。


1.棧

  這裡說的棧是java棧,請和本地方法棧區分開。棧是一種先入後出的資料結構,java在java.util 包下就有實現了的stack,她在jdk1.0就有了。整合自vector,是執行緒安全的。好了,我們來說說jvm裡面的棧,棧由一個個棧幀組成,棧幀裡面又包括運算元棧,區域性變量表,方法出口,動態連線等

運算元棧:用來存放中間結果。被看做是虛擬機器棧的工作空間。比如1+2+4 ,這個計算過程是1+2 = 3 ,3+4=7  3和7數值就是存放在運算元棧中。 1和2存放在區域性變量表中。

區域性變量表:用於存放方法引數和方法內部定義的區域性變數。

簡單的分析一下 1+2 對應的區域性變量表和運算元棧是怎麼工作的。javap -c <pid> 可以看到如下的資料結構。

  1. iload_0    
  2. iload_1      
  3. iadd        
  4. istore_2    

第1步,從區域性變量表索引為0的地方拿到值也就是1放到運算元棧中 。目前區域性變量表中有1,2兩個值 ,地址索0指向1, 地址索引1指向數值2。

運算元棧中有一個1。

第2步,從區域性變量表索引為1的地方拿到值也就是2放到運算元棧中 。目前區域性變量表中有1,2兩個值 ,地址索0指向1, 地址索引1指向數值2。

運算元棧中有兩個值,根據棧的先入後出知道 數值2在數值1的上面,也就是棧頂位置。

第3步,從運算元棧中彈出兩個數,相加,放到運算元棧中。目前區域性變量表中有1,2兩個值 ,地址索0指向1, 地址索引1指向數值2。

運算元棧中有一個值3。

第4步,將運算元棧棧頂的資料彈出,也就是3,放到區域性變量表裡面。目前區域性變量表中有1,2,3兩個值 ,地址索0指向1, 地址索引1指向數值2,地址索引2指向3.

運算元棧中已經沒有值了。

已上四步是詳細的步驟了,圖就不畫了。

2.堆

存放物件例項。

3.方法區

存放類的載入資訊和定義的類變數。

Student s = new Student("小明",18);

s 是指標,存放在棧中。

new Student("小明",18) 是物件 ,存放在堆中。

Student 類的資訊存放在方法區。

總結 :

物件的例項儲存在堆上,物件的元資料(instantKlass)儲存在方法區,物件的引用儲存在棧上。