Java 內存區域劃分

一、虛擬機運行時內存劃分

這裏寫圖片描述
由上圖可知,Java運行時數據區劃分爲五個部分,分別是程序計數器、虛擬機棧、本地方法棧、方法區、堆區。整個Java內存劃分除了運行時數據區還有直接內存。

二、各區域介紹

1. 程序計數器(Program Counter Register)

線程私有,代表着當前線程所執行字節碼的行號指示器。Java 虛擬機的多線程是通過線程輪流切換並分配處理器執行時間的方式實現的,因此爲了線程切換後還能恢復執行位置,每條線程都需要一個獨立的程序計數器。
如果線程正在執行的是一個 Java 方法,這個計數器記錄的是正在執行的虛擬機字節碼指令的地址;如果執行的是 Java Native 方法,這個計數器值爲空。
而且程序計數器是 Java 虛擬機中沒有規定任何 OutOfMemoryError 的區域。

2. 虛擬機棧(VM Stack)

線程私有,它的生命週期和線程相同。
描述的是 java 方法執行的內存模型:每個方法在執行的同時多會創建一個棧幀用於存儲局部變量表操作數棧動態鏈表方法出口等信息。
每一個方法從調用直至完成的過程,就對應着一個棧幀在虛擬機中入棧到出棧的過程。
局部變量表存放了編譯期可知的各種基本數據類型和對象引用和 returnAddress 類型(它指向了一條字節碼指令的地址),所需內存空間在編譯期確定
-Xoss 參數設置本地方法棧大小(對於 HotSpot 無效)
-Xss 參數設置棧容量 例: -Xss128k
1、當一個線程的棧深度大於虛擬機所允許的深度的時候,將會拋出 StackOverflowError 異常
2、如果當創建一個新的線程時無法申請到足夠的內存,則會拋出 OutOfMemeryError 異常。

3. 本地方法棧(Native Method Stack)

線程私有同虛擬機棧,只不過本地方法棧位虛擬機使用到的 native 方法服務。Sun HotSpot 虛擬機把本地方法棧和虛擬機棧合二爲一。

4. 堆(heap)

是虛擬機中最大的一塊內存區域了,被所有線程共享,在虛擬機啓動時創建。它的目的便是存放對象實例以及數組。堆是垃圾收集器管理的主要區域,因此 很多時候也被成爲‘GC’堆(Garbage Collected Heap)。從垃圾回收的角度來講,現在的收集器包括 HotSpot 都採用分代收集算法,所以堆又可以分爲:新生代(Young)和老年代(Tenured),再細緻一點,新生代又可分爲 Eden、From Survivor 空間和 To Survivor 空間。從內存分配的角度來講,又可以分爲若干個線程私有的分配緩衝區(Thread Local Allocation Buffer ,TLAB)。當堆空間不足切無法擴展,會拋出 OutOfMemoryError 異常。

5. 方法區(Method Area)

線程共享用於存儲已被虛擬機加載的類信息常量靜態變量即使編譯後的代碼等數據。當方法區無法滿足內存分配需求的時候,會拋出 OutOfMemoryError 異常。

6. 運行時常量池(Runtime Constant Pool)

用於存放編譯器生成的各種字面量和符號引用,這些內容將在類加載後進入方法區存放。運行時常量池相對於 Class 文件常量池的另外一個重要特徵是具有動態性,運行期間也可能有新的常量池放入持重,比如 String.intern() 方法。運行時常量池屬於方法區一部分,自然會拋出 OutOfMemoryError 異常

7. 直接內存

直接內存(Direct Memory)不屬於虛擬機中定義的內存區域,而是堆外內存。

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