Java記憶體模型

2021-09-08 07:28:58 字數 2106 閱讀 9760

棧:

基本資料型別直接在棧中分配空間,區域性變數(在方法**段中定義的變數)也在棧中直接分配空間,當區域性變數所在方法執行完成之後該空間便立刻被jvm**

引用資料型別,用關鍵字new建立出來的物件所對應的引用也是在棧空間中,此時,jvm在棧空間中給物件引用分配了乙個位址空間(相當於乙個門牌號,通過這個門牌號就可以找到你在堆中的家),在堆空間中給該引用的物件分配乙個空間,棧空間中的位址引用指向了堆空間中的物件區(通過門牌號找住址)

區域性變數,無預設值

堆:

一般用來存放用關鍵字new出來的資料

成員變數,有預設值

通過一段程式來說明執行時jvm的記憶體情況(僅看部分**即可):

package demo;

public class student

public string getname()

public void setname(string name)

public int getage()

public void setage(int age)

}

package demo;

public class studentdemo

}

當我們執行程式時,jvm會把student類與studentdemo類編譯完然後載入到jvm中乙個叫方法區的地方,類的成員變數與成員方法也被載入到方法區中,此時記憶體模型如下:

可以看到study方法右邊各有乙個16進製制的標記,而name與age變數沒有,這是因為每個物件都有各自的成員變數,而類中的成員方法卻可以被每個物件所共用,為了節省記憶體空間,jvm為方法分配了該標記(也叫記憶體位址)便於每個new出來的物件查詢呼叫,接著jvm會自動尋找main方法,在棧中為main方法申請乙個空間,這個過程也叫入棧,然後執行我們student類中第5行**

這時候,jvm在堆空間中分配一塊記憶體給student物件,並為其分配乙個記憶體位址並把物件的成員加到堆中,如果物件的成員變數沒有賦值,則jvm會為變數賦初始值在棧中分配一塊記憶體空間用於指向堆空間中的student物件區的記憶體位址。

【即:student s = new student();的過程:

1)student.class載入進記憶體(方法區); 

2)宣告乙個student型別引用s ;

3)在堆記憶體建立物件;

4)給物件中屬性預設初始化值;

5)屬性進行顯示初始化;

6)構造方法進棧,對物件中的屬性賦值,構造方法彈棧;

7)將物件的位址值賦值給s。】

此時記憶體模型如下

接著看**第8行與第9行

程式為student物件的成員變數賦值,jvm會根據student所指向的位址在堆記憶體中尋找student類的變數,並為變數賦新的值

第12行

這時student物件呼叫study方法,jvm在棧空間中為study方法申請了一塊記憶體空間

study方法執行完後,立即釋放棧空間,**第14行,

到這,main方法中所有**執行完畢,main方法所占用的棧空間也被**,而堆空間等待gc **

java記憶體模型

一 原子性 原子性是指乙個操作是不可中斷的,即使是多個執行緒一起執行的時候,乙個操作的開始,就不會被其他執行緒干擾 那麼有人會想到 i 是原子操作嗎?答案肯定不是。因為i 至少包含兩個操作,讀 從記憶體中讀出來 和行為 加上去 還有可能把加完後的資料在方法到i裡面去,出來也是1,這兩個執行緒同時進行...

Java記憶體模型

1.首先,執行緒a把本地記憶體a中更新過的共享變數重新整理到主記憶體中去。2.然後,執行緒b到主記憶體中去讀取執行緒a之前已更新過的共享變數。1.共享物件對各個執行緒的可見性 2.共享物件的競爭現象 指令級並行的重排序 如果不存l在資料依賴性,處理器可以改變語句對應機器指令的執行順序。記憶體系統的重...

Java記憶體模型

int x 0 thread a int y x thread bint x 5 int y 8 int z x y 關於上面的 存在這樣關係 x和z之間存在資料依賴關係,同時y和z之間也存在資料依賴關係。為了得到正確的結果,執行指令序列時,z不能重排序到x和y的前面。但是x和y之間並沒有資料依賴關...