標籤:
- 1. Java運行時資料區域
Java虛擬機器在執行java程式的過程中會把它管理的記憶體劃分為若干個不同的資料區域。
1.1程式計數器
程式計數器是一塊較小的記憶體空間,它可看做是當前線程所執行的位元組碼的行號指標。在虛擬機器的概念性模型裡(僅是概念性模型,各種虛擬機器可能會通過一些更高效的方式實現),位元組碼解譯器工作時就是通過改變這個計數器的值來選取下一條需要執行的位元組碼指令,分支、迴圈、跳轉、異常處理、線程恢複等基礎功能都需要依賴這個計數器來完成。
1.2java虛擬機器棧
與程式計數器一樣,java虛擬機器棧也是線程私人的,它的生命週期與線程相同。虛擬機器棧描述的是java方法執行的記憶體模型:每個方法在執行的同時都會建立一個棧幀用於儲存局部變數表、運算元棧、動態連結、方法出口等資訊。每個方法從調用至執行完成的過程,就對應著一個棧幀在虛擬機器棧中入棧到出棧的過程。
在java虛擬機器規範中,對這個地區規定了兩種異常情況:如果線程請求的棧深度大於虛擬機器所允許的深度,將拋出StackOverflowError異常;如果擴充時無法申請到足夠的記憶體,就會拋出OutOfMemoryError異常。
1.2.1局部變數表
局部變數表存放了編譯期可知的各種基礎資料型別 (Elementary Data Type)、對象引用和returnAddress類型。其中64位長度的long和double類型的資料會佔用2個局部變數空間(slot),其餘的資料類型只佔用1個。局部變數表所需的記憶體空間在編譯期間完成分配。
1.3本地方法棧
本地方法棧與虛擬機器棧所發揮的作用非常相似。
1.4java堆
Java堆是被所有線程共用的一塊記憶體地區,在虛擬啟動時建立。此記憶體地區的唯一目的就是存放對象執行個體,幾乎所胡的對象執行個體都在這裡分配。
Java堆是垃圾收集器管理的主要區域,因此很多時候也被稱做”Gc堆”。從記憶體回收的角度看,java堆還可以細分為:新生代和老年代;再細緻可分為eden空間、from survivor空間、to survivor空間等。
Java堆可處於物理上不連續的記憶體空間中。可以通過-Xmx和-Xms控制大小,如果在推中沒有記憶體完成執行個體分配,將會拋出OutofMemoryError異常。
1.5方法區
方法區與java堆一樣,是各個線程共用的記憶體地區,它用於儲存已被虛擬機器載入的類資訊、常量、靜態變數、即時編譯器編譯後的代碼等資料。
1.5.1運行時常量池
運行時常量池是方法區的一部分。Class檔案中除了有類的版本、欄位、方法、介面等描述資訊外,還有一項資訊是常量池,用於存放編譯期產生的各種欄位量和符號引用,這部分內容將在類載入後進入方法區的運行時常量池中存放。
運行期間也可能將新的常量放入池中,這種特性被開發人員利用的比較多的便是string類的intern()方法。
參考《深入理解java虛擬機器》
java 記憶體地區