java運行時和對象的內存佈局(深入理解Java虛擬機筆記)

目錄

程序計數器(PC寄存器)

Java虛擬機棧

本地方法棧

Java堆

方法區

直接內存

對象內存佈局

對象訪問定位


有的人寫博客給他人看,有的人寫博客給自己看,有的人寫博客只是記錄,有的人寫博客爲了展示,我都有。寫博客還有其他的目的和作用,看客可以自己用心體驗。

寫博客特別累,不是碼字類,而是看書動腦子累。今天打破下長時間的沉默,發表點大家常常掛在嘴邊的東西。

程序計數器(PC寄存器)

“線程私有”的內存區域,每條線程有一個。

存放的是正在執行的字節碼指令(在第三部分有講,方法會編譯成字節碼集存儲在方法表集合的屬性表集合裏“Code”屬性表的code屬性裏)的地址;若線程正在執行的是java方法,則存放的是該方法中對應的字節碼指令地址,若正在執行的是native方法,則其值爲未定義的值。

Java虛擬機棧

“線程私有”,生命週期和線程一樣。

描述java方法執行時的內存模型。爲每個執行的方法創建一個棧幀用於存儲局部變量表、操作數棧、動態鏈接、方法出口等信息。

存儲局部變量表存放各種編譯期可知的各種基本類型、對象引用(可能是對象起始地址,也可能是代表對象的句柄,還可能是對象相關的位置)、返回地址(指向了一條字節碼的地址)。局部變量表在幀中所需的內存空間在編譯期間就完全確定。

線程請求的棧深度大於虛擬機所允許的深度,拋出StackOverflowError異常;線程動態擴展棧的空間超過虛擬機規範所允許的固定長度,拋出OutOfMemoryError異常。

本地方法棧

“線程私有”。

本地方法棧也會拋出StackOverflowError異常和OutOfMemoryError異常。幀怎麼實現?

Java

線程共享。

物理空間可以不連續,邏輯空間連續即可。可擴展,但通過-Xmx和-Xms控制,超過時拋出OutOfMemoryError異常。其中各個區域的劃分,分配,回收參見“垃圾收集器與內存分配策略”部分。

方法區

線程共享。

存儲已被虛擬機加載的類信息(包含Class文件中的常量池)、常量、靜態變量、即時編譯器編譯後的代碼等。別名Non-Heap。

本質上和“永久代”並不等價,只能說HotSpot虛擬機的一些版本把GC分代收集區域擴展至方法區。然而方法區可以選擇不實現垃圾收集。

HotSpot虛擬機可以通過下面的參數來限制“永久代”的大小(方法區大小限制[包括運行時常量池的大小限制])。

運行時常量池是方法區的一部分。Class文件中的常量池包含編譯期生成的各種字面量和符號引用,這些內容在類加載後存在方法區的運行時常量池,這個池子還會存儲翻譯出來的直接引用。Java虛擬機規範並沒有對該池做任何要求,編譯期的常量可以存放,運行期的常量也可以存放,例如:String的intern方法。

物理空間可以不連續,邏輯空間連續即可。可以選擇固定的大小或者可擴展,超出時拋出OutOfMemoryError異常。

直接內存

不是運行時數據區域的一部分,也不是java虛擬機規範中的定義的內存區域,不受java堆大小的限制。例如可以通過存儲在java堆中的DirectByteBuffer對象作爲這塊直接內存的引用來進行操作,或者通過JNI來分配直接內存來使用。

/**
 * VM Args:-Xmx20M -XX:MaxDirectMemorySize=10M
 * @author zzm
 */
public class DirectMemoryOOM {

	private static final int _1MB = 1024 * 1024;

	public static void main(String[] args) throws Exception {
		Field unsafeField = Unsafe.class.getDeclaredFields()[0];
		unsafeField.setAccessible(true);
		Unsafe unsafe = (Unsafe) unsafeField.get(null);
		while (true) {
			unsafe.allocateMemory(_1MB);
		}
	}
}

 

 

對象內存佈局

對象在內存中的佈局分爲3塊區域:對象頭(Header)、實例數據(Instance Data)和對齊填充。

對象頭有2部分信息:自身的運行時信息,哈希碼,GC分代年齡,鎖狀態標誌,線程持有的鎖等,具體查書;對象類型數據指針。

實例數據是各種類型的字段的內容。有存儲順序的策略一講。

從對象起始地址起8字節對齊,不足填充。

對象訪問定位

目前主要有2種訪問方式:

珍惜他人勞動成果,筆記轉載時,請掛上本文鏈接。

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