棧:
基本資料型別直接在棧中分配空間,區域性變數(在方法**段中定義的變數)也在棧中直接分配空間,當區域性變數所在方法執行完成之後該空間便立刻被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之間並沒有資料依賴關...