1. 程式人生 > 程式設計 >JVM記憶體模型(執行時資料區)

JVM記憶體模型(執行時資料區)

JVM記憶體模型

  • 方法區
  • 程式計數器
  • 本地方法棧

每個執行緒私有,有幾個執行緒就會有幾個棧.棧也是一種資料結構,遵循FILO(先進後出),線上程建立執行方法時都會建立一個棧幀,進行壓棧的操作.最先進行壓棧的棧幀最後出來,最後壓棧的棧幀最先出來.可以理解為棧是一個封住底的桶,而棧幀就是一個放入桶中,切面面積與桶相等的木塊,你需要先取出後面放進去的木塊,才能取出前面的.

棧幀中結構

在每個棧幀棧幀中都會儲存幾個常見的結構(我也不知道怎麼講) 如: 區域性變量表,運算元棧,動態連結,方法出口(見圖一).

  • [1] 區域性變量表 : 儲存同一方法內的區域性變數,如(int a,String str)這裡的a和str.區域性變數中的物件控制程式碼有指向堆記憶體具體物件位置的指標
  • [2] 運算元棧 : java檔案會被編譯為class位元組碼檔案,位元組碼檔案又會被翻譯成機器碼.運算元棧就是程式執行在執行JVM指令的時候,運算元的中轉站(運算元棧也是一種棧結構).比如下例 int a = 1; int b = 2; int c = a+b;此時程式執行時會將1壓入運算元棧,然後進行彈棧將1彈出來賦給a(第一行程式碼),然後將2壓入棧,彈出2賦給b(第二行程式碼),將1和2壓入棧(分兩步進行),將1和2彈出棧,計算出結果3並賦值給c(第三行程式碼). java中任意資料型別都可以放入運算元棧,32位資料佔據棧容量為1,64位佔據棧容量為2.
  • [3] 方法出口 : 記錄著程式從什麼時候進入這個方法,以便方法結束後,棧幀被彈出返回原程式執行位置.
  • [4] 動態連結 : 在程式執行期間將常量池中的符號替換為直接引用

程式計數器

每個執行緒私有,記錄著程式執行期間,jvm指令執行的行數.

本地方法棧

用於執行本地方法的棧,每個執行緒私有.在java中有很多底層方法用native修飾,這些方法就是本地方法,本地方法是用其他語言寫的比如c.

存放物件的位置.堆中分為年輕代和老年代.記憶體分配佔比預設為1:2.在年輕代中分為Eden區,Survivor區(分為兩部分,S0,S1),Eden:S0:S1:1:1.在物件新建之初物件會被放入Eden區,當這一區放滿會觸發Young GC,清理掉死亡物件,將剩餘存活物件移入到S0區,S0區放滿後依然會觸發Young GC,並將剩餘存活物件放入S1區,S1區滿後依然會觸發Young GC,並將剩餘存活物件放回From區.

也就是說年輕代的三個分割槽在放滿後都會觸發,Young GC並移動剩餘存活物件

Eden區剩餘存存活物件移入Survivor區,在Survivor區中,S0和S1的剩餘存貨物件都會移入到另一個區,在物件每次進行移動操作時物件頭中儲存的迭代年齡會+1,當迭代年齡達到15,就會把物件移入到老年代.當老年代存滿後會觸發Full GC(Full GC會停止掉其他工作程式).

方法區

方法區也叫元空間,存放著常量池,靜態變數,類的元資訊等.堆中的物件會指向方法區中對應的類的資訊.