深入理解Java虛擬機(二) --- JVM內存管理


運行時的數據區域

在這裏插入圖片描述



一.程序計數器

目的:作爲當前線程所執行字節碼的行號指示器

原理:通過字節碼解釋器改變計數器的值來選取下一條字節碼指令

特點
1.佔用較小的內存空間

​ 2.每條線程需要一個獨立的程序計數器

​ 3.Native方法不需要程序計數器,因爲它不需要解釋器

​ 4.不同線程的該內存區域相互獨立

方法類型 計數器狀態
Java方法 記錄正在執行字節碼地址
Native方法

異常處理: 當沒有內存區域可擴展的時候,拋出OutOfMemoryError



二.Java虛擬機棧

目的:描述Java執行時的內存模型

原理:當一個JAVA方法執行的時候,會在虛擬機棧上建立一個棧幀,用來保存 局部變量表操作數棧,動態鍵棧,方法出入的信息(eg:方法返回值)。

特點
1.廣義上的棧就是指的是,虛擬機棧中的幾部變量表

​ 2.進入一個方法時,局部變量空間是確定的,不會再改變

​ 3.不同線程的該內存區域相互獨立

異常處理
1.若線程請求的棧深度 > 虛擬機允許的深度,拋出StackOverflowError

​ 2.若動態虛擬機棧可以動態擴展(絕大多數),若擴展時無法申請足夠的內存,拋出 OutOfMemoryError


局部變量表:

目的:使用 局部變量表 完成參數值到 參數變量列表 的傳遞過程

原理:是一個以字長爲單位的數組,用於存放方法參數 和 方法內定義的局部變量索引

索引類型包括:基本變量類型,對象引用類型, returnAdress類型

1.reference類型(對象引用類型),作爲對象引用指針,指明瞭對象在 JAVA堆 中的起始地址 和在 方法區 的對象類型數據
2. returnAdress類型,指向一條字節碼指令的地址

  • 局部變量表中一個slot代表一個變量槽,長度和CPU架構的位長是相同的。

  • 64位長度的long和double類型佔用2個局部變量表空間(slot),其他的均爲1個單位大小。

  • 在第0位slot處存放該方法所屬對象實例的引用(在Java堆中),程序中用this關鍵字進行訪問

  • 可複用:超出作用域的slot變量將被GC回收進行覆寫


操作數棧

目的:作爲JVM的工作區,對數據進行操作。

原理:同樣也是一個以字長爲單位的數組,用於存放操作數的值。大多數指令都要從這裏彈出數據,執行運算,然後把結果壓回操作數棧。

解析:

void Method(){
    int a = 1;
    int b = 2;
    int result = a + b;
}

在這裏插入圖片描述

內部過程

1.在局部變量表分配三個slot,分別指向 a , b,result。其中 a,b有初值

2.將局部變量表中的a,b的值放入操作數棧。

3.在操作數棧中彈出a,b的值彈出進行運算,接着將結果壓入操作數棧中。

4.從操作數棧彈出結果,放到局部變量表中result相應的位置



三.本地方法棧

目的:描述Native方法執行時的內存模型

原理: 形如Java虛擬機棧

特點: 不同線程的該內存區域相互獨立

異常處理: 與Java虛擬機棧出現的異常是相同的

有些虛擬機會將本地方法棧與Java虛擬機棧合二爲一(eg:HotSpot虛擬機)



四.Java堆

目的: 存放幾乎所有對象的實例

原理: 將實例存放在一塊 物理不連續,但是邏輯上連續的內存空間上。

特點:
1.是JVM管理的內存中最大的一塊區域

​ 2.所有線程共享一塊內存區域

異常處理: 通常實例分配的時候,堆是可擴展的,但是當無法再擴展的時候,會拋出OutOfMemoryError



五.方法區(非堆)

目的: 作爲Java堆的邏輯部分

原理: 存儲已被虛擬機加載的 類信息,常量,靜態變量,即時編譯器編譯後的代碼 等數據

特點:
1.物理不連續

​ 2.所有線程共享一塊內存區域

​ 3.可以選擇不實現GC

異常處理: 雖然方法區是可以擴展的,但是當無法滿足內存分配時,拋出OutOfMemoryError


運行時常量池

目的: 是方法區的一部分,用於存放編譯期間生成的各種字面量與符號

原理: 在類加載後,將“常量”存放在該區域

特點: 動態性:在運行期間也能將新的常量放入池中

​ eg:String類的intern方法(TODO )


JDK1.8後字符串常量池放到了堆中,不再是在方法區中,而是在Java堆中



直接內存

目的: 直接引用分配在Java堆外Native函數庫的內存,避免了Java堆與Native堆來回複製操作

原理: 通過一個存儲在Java堆中的DirectByteBuffer對象,作爲這塊內存的引用進行操作

特點: 顯然直接內存分配不受Java堆大小限制,但受到本機物理的內存大小限制。

異常處理: 當佔用總和超出物理內存大小限制的時候,拋出OutOfMemoryError

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