1.運行時數據區域
Java虛擬機在執行Java程序的過程會把它管理的內存分成若干個不同的數據區域。各個部分有各個部分的作用。有以下幾個主要部分:
1.程序計數器(線程私有)
程序計數器是一塊較小的內存空間,可以看作當前線程所執行的字節碼的行號執行器。字節碼解釋器工作時通過改變計數器的值來選取下一條需要執行的字節碼指令。
2.Java虛擬機棧(線程私有)
(約等於平時我們說的內存的棧)
描述方法執行的內存模型:方法執行時會創建一個棧幀,存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。方法執行的過程,對應着棧幀在java虛擬機棧中入棧、出棧的過程。
平時所說的棧差不多就是這個區域,準確的說,是虛擬機棧中的局部變量表部分:
主要存放:已知的基本數據類型(8種)、對象引用、返回地址。
所需內存:編譯時即分配。當進入一個方法時,所需在幀中分配多大的局部變量空間時完全確定的,運行期間不會改變。
3.本地方法棧
類似於上面2。區別:Java虛擬機棧是爲虛擬機執行Java方法服務的,本地方法棧是爲虛擬機執行Native方法服務的。有的虛擬機把這兩個合併爲一了。
4.Java堆(線程共享)
這是佔內存最大的部分。虛擬機啓動時即被創建。
主要存放: 對象的實例、數組
堆可處於物理上不連續,邏輯上連續的內存空間。
5.方法區(線程共享)
主要存放: 已被虛擬機加載的類信息、常量、靜態變量。
2.對象的創建
創建過程:
1. 類加載檢查
虛擬機遇到new指令,首先會檢查指令的參數是否在常量池中定位到一個類的符號引用,並檢查目標類是否加載、解析和初始化過。
2.分配內存
對象所需的內存空間確定後,需要從java堆中劃分確定大小的部分給目標類。有兩種方式:
指針碰撞: java內存規整。用過的在一邊,沒用過的在一邊,中間有指針。分配空間時可以通過移動指針來完成。
空閒列表: Java內存不規整。有列表記錄空閒的內存塊。在分配時,查詢空閒的部分進行分割。
3.內存空間初始化。
目的:對象的實例在Java代碼中可以不賦初值就可以使用。
4.對象進行必要的設置
例如:對象是哪個類的實例、如何找到類的元數據信息、對象的哈希碼、對象的GC分代年齡等。