JVM_01虛擬機內存劃分

JAVA技術:在虛擬機層面隱藏了底層技術的複雜性以及機器與操作系統的差異性。從而導致一旦出現Java內存區域和內存溢出異常時,如果不瞭解JVM的工作機制,排查錯誤將十分艱難。

1. JVM對其管理的內存區域劃分

所劃分的這些數據區域是線程隔離的。

1)程序計數器

時一塊較小的內存空間,可作爲線程所執行字節碼的行號指示器。JVM的多線程通過其保證線程切換時能夠恢復到正確位置,每條線程都需要一個獨立的程序計數器,各線程計數器互不影響,獨立存儲。

2)JAVA虛擬機棧(JVM Stacks)

線程私有的,生命週期與線程相同。虛擬機棧描述的Java方法執行的內存模型:每個方法執行時都會創建一個棧幀以存儲局部變量表、操作數棧、動態鏈接、方法出口等信息

## 局部變量表存放了編譯器的基本數據類型、對象引用。局部變量表所需的內存空間在編譯期間完成分配,方法運行時不會改變表的大小。當線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError。如虛擬機棧可擴展,但擴展也無法申請到足夠內存時,拋出OutOfMemoryError。

3)本地方法棧(Native Method Stacks)

JVM Stacks爲JVM執行的Java方法(字節碼)服務,而NMS則是爲虛擬機使用到的Native方法服務。虛擬機規範並沒有對本地方法棧中的方法使用的語言、使用方式與數據結構並沒有強制規定,具體的虛擬機可以自由的實現它。

4)堆

JVM所管理的內存中最大的一塊。堆時被所有線程共享的一塊內存區域,在虛擬機啓動時自動創建。用於存放對象實例,堆是垃圾收集器管理的主要區域,很多時候稱爲GC堆。目前收集器多采用分代收集算法,Java堆可以細分爲:新生代和老年代。堆可以處於物理上不連續的內存空間中。

5)方法區

各個線程共享的內存區域,用於存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據

## 運行時常量池

是方法區的一部分,用於存放編譯期生成的各種字面量和符號引用

2. 對象的訪問

Object obj = new Object();

1)Object obj存放於棧的本地變量表中,作爲一個reference類型數據

2)new Object() 存放於堆中,形成一塊存儲裏Object類型所有實例數據值得結構化內存,根據具體類型以及JVM實現的對象內存佈局不同,這塊內存的長度也不固定。

3)此對象類型數據的地址信息(對象類型、父類、實現接口、方法)存儲在方法區中。

訪問方式:使用句柄或直接指針

1)使用句柄

堆中劃分出一塊內存作爲句柄池,reference中存儲的是對象的句柄地址,句柄中包含對象實例數據和類型數據各自的具體地址信息

優點:對象被移動(垃圾回收時移動對象很普遍)只需改變句柄中的實例數據指針,reference本身無需更改

2)直接指針

堆中要考慮如何放置訪問類型數據的相關信息,reference中直接存儲對象地址

優點:速度快,少了一次定位指針的時間開銷

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章