java內存區域模型
Java虛擬機在執行Java程序的過程中,會把它所管理的內存區域劃分爲若干個不同的數據區域,這些區域一般被稱爲運行時數據區(Runtime Data Area),也就是我們常說的JVM內存。
運行時數據區通常包括以下這幾個部分:
- 程序計數器(Program Counter Register)
- 虛擬機棧(VM Stack)
- 本地方法棧(Native Method Stack)
- 堆(Heap)
- 方法區(Method Area)
1. 程序計數器
程序計數器是一塊較小的內存空間,它可以看做是當前線程所執行的字節碼的行號指示器。字節碼解釋器在工作時,會通過改變這個計數器的值來取下一條語句指令。每條線程都需要一個獨立的程序計數器,各條線程之間計數器互不影響,獨立存儲,我們稱之爲線程私有
2. java虛擬機棧
虛擬機棧描述的是Java方法執行的內存模型:每個方法在執行的同時都會創建一個棧幀用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。每一個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。與程序計數器一樣,虛擬機棧也是線程私有的,它的生命週期與線程相同
局部變量表
- 存放編譯期可知的各種基本數據類型(boolean、byte、char、short、int、float、long、double),引用類(refrence)型,returnAddress(指向了一條字節碼指令的地址)類型。
- 局部變量表的內存空間在編譯期完成分配,當進入一個方法時這個方法需要在幀分配多少內存是固定的,在方法運行期間是不會改變局部變量表的大小的。
在Java虛擬機規範中,對這個區域規定了兩種異常狀況:如果線程請求的棧深度大於虛擬機所允許的深度,將拋出StackOverflowError異常;如果虛擬機可以動態擴展,擴展時無法申請到足夠的內存,將會拋出OutOfMemoryError異常
3. 本地方法棧
本地方法棧和虛擬機棧發揮的作用是非常類似的,他們的區別是虛擬機棧爲虛擬機執行Java方法(也就是字節碼)服務,而本地方法棧則爲虛擬機使用到的Native方法服務
本地方法棧區域也會拋出StackOverflowError和OutOfMemoryErroy異常
4. java堆
Java堆是被所有線程所共享的一塊內存區域,在虛擬機啓動時創建。此內存區域的唯一目的就是存放對象實例和數組,幾乎所有的對象實例都在這裏分配內存。Java堆是垃圾收集器管理的主要區域,因此很多時候也稱作爲"GC"堆。如果在堆中沒有內存完成對象實例的分配,並且堆也無法再擴展時,將會拋出OutOfMemoryError異常
5. 方法區
方法區與Java堆一樣,是各個線程共享的內存區域,它用於存儲已被虛擬機加載的類信息(包括類的版本,字段,方法,接口)、常量、靜態變量、即使編譯器編譯後的代碼等數據
運行時常量池(Runtime Constant Pool)
- 方法區的一部分,用於存儲編譯期生成的各種字面量、符號引用,這部分內容將在類加載後進入方法區的運行時常量池中存放
根據Java虛擬機的規定,當方法區無法滿足內存分配需求時,將拋出OutOfMemoryError異常