輕鬆搞定java記憶體模型(一)基本組成
Java記憶體大概模型如上圖,包含五大部分,其中方法區和堆是執行緒共享的,虛擬機器棧,本地方法棧,程式計數器是執行緒私有的。
1:程式計數器
程式計數器可以看做當前執行緒所執行的位元組碼(可以簡單理解為java類經過編譯後便是位元組碼)的行號指示器,位元組碼直譯器通過改變程式計數器的值來選區下一條需要執行的位元組碼指令。
如果正在執行的是一個java方法,計數器記錄的是正在執行的虛擬機器位元組碼指令的地址,如果正在執行本地方法,計數器則為空。
通俗來說,程式計數器指向的是當前正在執行的某行java程式碼。本地方法是java呼叫非java程式碼的介面,該方法的實現由非java語言來實現(navtive method
2:虛擬機器棧
虛擬機器棧描述的是java方法執行的記憶體模型,每個方法執行的同事建立一個棧幀(方法執行時的基礎資料結構),用於儲存區域性變量表,運算元棧,動態連結等。每個方法呼叫的整個過程可以看做一個其對應棧幀入棧出棧的過程。
其中區域性變量表,存放了編譯期可知的各種基本資料型別(boolean ,byte,char,short等),物件引用(只是一個指向物件起始地址的指標)
通俗來說,虛擬機器棧,就是我們常說的“堆疊”中的棧,只不過具體要更復雜。我們常說的棧,可以看做虛擬機器棧的區域性變量表。
3:本地方法棧
如上,虛擬機器棧為java方法服務,本地方法棧當然就是為本地方法服務的棧。
小小結:程式計數器,本地方法棧,虛擬機器棧可以看做對於一個執行緒的描述,他們沒有存放物件的實體,但是存放了對於物件實體的描述,所以個人覺得這三個部分可以看做執行緒的描述,所以都是執行緒私有的。
4: 堆
眾所周知,java堆就是存放物件例項的地方,所有的物件都存放在堆中,所以堆肯定是執行緒共享的。
5:方法區
方法區用於存放已經被虛擬機器載入的類資訊,常量,靜態變數,JIT(即時編譯器)編譯後的程式碼等資料。通常來說,方法區存放著.class檔案的二進位制檔案,而在堆存放這個類的java.long.class
小小結:
方法區和堆存放的物件相關的東西,方法區存放物件的描述,可以看做一個物件的模型,堆中存放著根據這個模型建立的物件,所以方法區和對肯定是對執行緒共享的(每個執行緒都要使用很多類啊,一個類要被多個執行緒使用啊)。
小結:
Java記憶體模型中的這五部分是個基礎,深入很複雜。筆者認為可以從執行緒和物件建立兩個方面去理解,方法區和堆與物件相關,虛擬機器棧,本地方法棧,程式計數器與執行緒相關。