《深入理解Java虛擬機》第二章筆記
目錄
1 運行時數據區域
包含五個部分:
線程共享:方法區、堆
線程隔離:虛擬機棧、本地方法棧、程序計數器
1.1 程序計數器
(1)佔用內存空間較少,可以被看作當前線程所執行的字節碼的行號指示器。
(2)如果線程正在執行Java方法,則程序計數器記錄的是字節碼指令的地址;如果正在執行Native方法,則計數器值爲空
(3)在Java虛擬機規範中唯一一個沒有規定任何OutOfMemoryError情況的區域。
1.2 Java虛擬機棧
(1)存儲的是一個個棧幀,棧幀中存儲的是局部變量表、操作數棧、動態鏈接、方法出口信息等(每個方法從調用直至執行完成,就對應着一個棧幀在虛擬機棧中的入棧和出棧)。
(2)異常:若線程請求的棧深度大於虛擬機所允許的深度,則拋出StackOverflowError異常;若虛擬機可以動態擴展,且擴展時無法申請到足夠的內存,則拋出OutOfMemoryErrory異常。
1.3 本地方法棧
(1)與虛擬機棧作用類似。與Java虛擬機棧區別是:Java虛擬機棧爲執行Java方法服務,而本地方法棧爲Native方法服務。
(2)與虛擬機棧類似,也會拋出StackOverflowError異常和OutOfMemoryErrory異常。
1.4 Java堆
(1)佔用內存空間最大,該區域的唯一目的就是存放對象實例。
(2)若在堆中沒有內存進行分配,且無法再擴展,則拋出OutOfMemoryError異常。
1.5 方法區
(1)存儲已被虛擬機加載的類信息、常量、靜態變量、即時編譯器編譯後的代碼等數據。
(2)若方法區中沒有內存進行分配,則拋出OutOfMemoryError異常。
1.6 運行時常量池
(1)是方法區的一部分。
(2)Class文件中的常量池存放的是編譯期生成的各種字面量和符號引用,這部分內容將在類加載後進入運行時常量池存放。
(3)若沒有內存進行分配,則拋出OutOfMemoryError異常。
1.7 對象的內存佈局
對象在內存中的佈局可分爲三部分:對象頭、實例數據、對齊補充。
①對象頭分爲兩部分,第一部分存儲對象自身的運行時數據(eg:哈希碼);第二部分是類型指針,即指向它的類元數據的指針
②實例數據對象真正有用的信息,即程序中定義的各種類型的字段內容。
③對齊補充,非必然存在,僅作佔位符作用,滿足對象起始地址必須是8字節的要求。
1.8 對象的訪問定位
訪問方式有兩種:句柄和直接指針。
優缺點:使用句柄的優勢是穩定的句柄指針,當對象被移動時只會改變句柄中的實例數據指針;使用直接指針的優勢是速度更快,它節省了一次指針定位的時間開銷。