筆記:《深入理解Java虛擬機》第二章-Java內存區域與內存溢出異常

                      《深入理解Java虛擬機》第二章筆記

目錄

1 運行時數據區域

1.1  程序計數器

1.2  Java虛擬機棧

1.3  本地方法棧

1.4  Java堆

1.5  方法區

1.6  運行時常量池

1.7  對象的內存佈局

1.8  對象的訪問定位


1 運行時數據區域

    包含五個部分:

        線程共享:方法區、堆

        線程隔離:虛擬機棧、本地方法棧、程序計數器

圖1.1  Java虛擬機運行時數據區

 

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  對象的訪問定位

    訪問方式有兩種:句柄和直接指針。

圖1.2  通過句柄訪問對象

 

圖1.3  通過直接指針訪問對象

 

     優缺點:使用句柄的優勢是穩定的句柄指針,當對象被移動時只會改變句柄中的實例數據指針;使用直接指針的優勢是速度更快,它節省了一次指針定位的時間開銷。

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