【JVM】JVM運行時數據區域

引言:Java虛擬機在執行Java程序的過程中,會把它管理的內存劃分爲若干個數據區域。這些區域有各自的特點與用途。以下是簡圖


一,這些數據區域分爲兩類


1,線程隔離的數據區:這些區域則是依賴用戶線程的啓動和結束而建立和銷燬。

包括:程序計數器,Java虛擬機棧,本地方法棧

特點:Java垃圾回收機制並不關注這個三個區,因爲隨着線程的結束,內存自然就隨着被回收了


2,由所有線程共享的數據區:這些區域隨着虛擬機進程的啓動而存在。

包括:方法區,堆

特點:Java中的垃圾收集器所關注的就是線程隔離的數據區,即方法區和堆。



二,JVM運行時五個數據區域的主要特點


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

作用:當前線程所執行的字節碼的行號指示器

特點:

1)每條線程都有一個獨立的程序計數器,互不干擾,獨立存儲,所以我們稱它爲“”線程私有“的區域。

2)如果線程正在執行一個java方法,程序計數器記錄的是正在執行的虛擬機字節碼指令的地址,如果正在執行的是native方法,則計數器值爲空。

3)程序計數器是唯一一個Java虛擬機中沒有規定任何OutOfMemoryError情況的區域。


2,Java虛擬機棧(Java Virtual Machine Stacks)

作用:描述Java方法執行的內存模型。每個方法被執行時都會創建一個棧幀,棧幀中存儲着這個方法的局部變量表等等相關信息,每個方法的棧幀都進棧放到Java虛擬機棧,棧幀進棧對應着方法開始執行,棧幀出棧對應方法執行結束。

特點:

1)平時大家把Java內存區分爲堆內存(Heap)和棧內存(Stack),這種方法比較粗糙,其實此處的”棧“就是這裏的Java虛擬機棧,或者說是虛擬機棧中的局部變量表部分。

2)每個方法的棧幀分配多大的局部變量空間表示在編譯期間確定的,在方法運行期間不會改變局部變量表的大小。

3)這個區域有兩種異常

a,StackOverflowError異常:線程請求的棧深度大於虛擬機所允許的深度(不可以動態擴展)

b,OutOfMemoryError異常:虛擬機棧可以動態擴展,擴展時無法申請到足夠的內存。


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

作用:本地方法棧和虛擬機棧所發揮的作用相同,但是針對的是native方法。

特點:拋出StackOverflowError異常與OutOfMemoryError異常,拋出的原理和虛擬機棧對應的原理相同。


4,Java堆(Java Heap)

作用:此內存的唯一目的就是存放對象實例與數組。(但是隨着一些新的技術的發展,比如JIT編譯器,逐漸出現了棧上分配等等方式)

特點:

1)垃圾收集器管理的主要區域就是Java堆,Java堆是被所有線程共享的一塊內存區域,此內存區域的唯一目的是存放對象實例。

2)Java堆是垃圾收集器管理的主要區域,也是我們常說的“GC堆”,現在收集器基本都是採用分代收集算法,所以Java堆中還可以細分爲:新生代和老年代。

3)Java堆不一定要處於物理上的連續狀態。只需要是邏輯上連續即可。

4)Java堆可以設置爲固定大小或者可擴展的。當前主流的虛擬機都是設置爲可擴展的(通過-Xmx和-Xms控制),所以一般情況下Java堆拋出的異常是:OutOfMemoryError異常


5,方法區(Method Area)

作用:存儲已被虛擬機加載的類信息,常量,靜態變量等數據

特點:

1)和Java堆類似,方法區在物理上可以不連續,可以選擇固定大小或者擴擴展。

2)方法區是Java堆的一個邏輯部分,但是可以不實現垃圾回收,垃圾收集行爲在這個區域極少出現。但是還是必須適當地進行垃圾回收,主要是針對其中的常量池。


tips:

StackOverflowError異常:線程請求的棧深度大於所允許的深度(不可以動態擴展)

OutOfMemoryError異常:某個區域可以動態擴展,擴展時無法申請到足夠的內存(可擴展)


其他

關於運行時常量池以及直接內存,後續再學習。



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