那麼沒有錯,我碼仔也要開始周志明的JVM之路,整本書模塊很多,只取需要的部分進行學習,如果其中有什麼錯誤的理解,請各位指出,讓我能認識到不足的地方,謝謝。
Tip: 始終追尋第一遍是記憶,第二遍是修改,第三遍是回顧加修改
JVM運行時數據區
本部分採用是否線程隔離/線程共享來描述這個數據區可能會比較切實點。
當然也有切分成數據流與指令流來描述,如下
但是我採用的是這個↓
一、程序計數器(Program Counter Register)
簡略: 用於指定當前字節碼解析行號的指示器(在掛起的時候記錄運行的行號、地址,喚醒時恢復執行到的行號、地址)
根據多線程的CUP時間片分配機制,我們可以瞭解到,同一時間一個處理器只會執行一個條線程中的指令 。
同時以防線程間切換CPU後不能恢復到原來的位置,因此每條線程都需要一個獨立的程序計數器,屬於線程隔離(線程私有的內存)。
tips:唯一一個虛擬機規範中沒有規定情況的內存區域
二、虛擬機棧
也歸屬線程私有,存儲當前線程運行方法所需數據、地址及指令
這裏提點到一個詞:棧幀(Stack Frame)
文字描述可能比較枯燥:這裏以方法Helloworld爲例子
(每一個方法從調用直到執行完成的過程,對應着一個棧幀在虛擬機中從入棧到出站的過程)
局部變量表與操作數棧
參考方法用於展示
public class hi{
public static int fine(int i){
int c = i;
return c++;
}
}
上述過程:
0 - 傳入變量壓入到操作數棧
1 - 彈出棧頂元素,存放到局部變量第一個位置
2 - 將局部變量第一個加載到操作數棧
3 - 棧頂局部變量做自增操作
6 - 從當前方法返回int
操作數棧與局部變量(基本類型)的操作:
①將一個局部變量加載到操縱棧的指令包括:iload_、lload…
②將一個數值從操作數棧存儲到局部變量表的指令包括:istore_、lstore…
(這裏說到了指令集的方法,也是另一種說歸屬於指令流劃分的原因)
如果是引用對象: 會指向Heap(堆)
一個局部變量表的單位:佔用32位的存儲空間(一個存儲單位稱之爲slot,槽),long和double需要2個連續的局部變量單位
動態連接
類似一個接口,實現它的方法,是要動態找它的實現類,並獲取其中要執行的方法,這也屬於動態鏈接的一個部分
tip: 本內存區域允許異常:
1、線程方法請求棧深度超過虛擬機所允許深度(通常類遞歸會出現),則會拋出異常
2、如果虛擬機棧動態拓展(通常兩種方式:Segmented stack和Stack copying),如果拓展的時候無法申請到足夠的內存,則會拋出異常
本地方法棧
與虛擬機棧發揮作用相似,具體實現交由虛擬機實現,不限制語言不拓展這個方向,不是主要關心的內容,暫時來講