深入理解JVM - 運行時數據區

運行時數據區

Java虛擬機在執行程序的過程中,會將內存劃分爲若干個不同的數據區域,這些若干個不同的數據區域組合在一起稱爲運行時數據區。運行時數據區可劃分爲兩類。一類是線程獨有的(程序計數器、Java虛擬機棧、和本地方法棧),隨線程的啓動和結束而建立和銷燬;另一類是所有線程共享的(Java堆和方法區),隨着虛擬機進程的啓動而一直存在。
在這裏插入圖片描述

程序計數器

每個線程都有一個獨立的程序計數器,各個線程之間的計數器互不影響。程序計數器記錄了字節碼指令的地址,他用來告訴線程應執行哪條指令。

Java虛擬機棧

Java虛擬機棧爲執行Java方法提供服務。每一個方法被調用到執行結束的過程,對應着一個棧幀在虛擬機棧中從入棧到出棧的過程。

棧幀

每一個棧幀都包含局部變量表、操作數棧、動態連接、方法返回地址等信息。棧幀中需要多大的局部變量表,需要多深的操作數棧在編譯期就已經被計算出來,並且寫入到方法表的Code屬性之中。也就是說,一個棧幀需要分配多大的內存在編譯期已經決定,不受運行期的影響。

  • 局部變量表的大小在編譯期就已經確定,該大小存儲在方法表的Code屬性之中。局部變量表存放了編譯期可知的各種Java虛擬機基本數據類型、對象引用。
  • 操作數棧的深度在編譯期就已經確定,該深度也存儲在方法表的Code屬性之中。我們可以將操作數棧理解爲數據計算的區域。
  • 動態連接 每一個棧幀都有一個指向運行時常量池中該方法的引用。這個引用用來支持方法調用過程中的動態連接。
  • 方法返回地址由PC計數器或異常表來確定。如果是正常退出,方法的返回地址就是主調方法調用點地址;如果是異常退出,方法的返回地址通過異常表來確定。
    前面提到方法退出的兩種方式。正常退出是指執行引擎遇到方法返回的字節碼指令,這個時候會將返回值傳遞給上層的方法調用者。異常退出是指方法在執行的過程中,某些指令導致Java虛擬機拋出異常並且該異常在本方法的異常表沒有辦法處理,或者Athrow字節碼指令顯示拋出異常並且在本方法中沒有進行異常捕獲,這個時候就會導致方法退出。如果是異常退出,是一定不會有返回值給上層方法調用者的。無論哪種退出,都需要恢復上層方法的局部變量表和操作數棧;如果有返回值,需要將返回值壓入調用者棧幀的操作數棧中;還需要調整PC計數器指向方法調用的後面一條指令。

本地方法棧

本地方法棧與Java虛擬機棧的作用類似,爲執行本地方法提供服務。

Java堆

Java堆是被所有線程共享的一塊內存區域,幾乎所有的對象實例都分配在這塊內存區域。

方法區

方法區也是被所有線程共享的一塊內存區域,它用於存儲已被虛擬機加載的類型信息、字段信息、方法信息、常量、靜態變量等數據。

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