JVM內存模型整理

Table of Contents

  1. 內存模型圖
  2. 詳細介紹
    1. 程序計數器PC
    2. 虛擬機棧
    3. 本地方法棧
    4. 方法區
    5. Java堆


  • 一般地大家講到的Java內存其實就是Jvm內存
  • Java代碼是運行在Java虛擬機之上的,由Java虛擬機通過解釋執行(解釋器)或編譯執行(即時編譯器)來完成,故Java內存模型,也就是指Java虛擬機的運行時內存模型。

內存模型圖

詳細介紹

程序計數器PC

  • 程序計數器PC,當前線程所執行的字節碼行號指示器。每個線程都有自己計數器,是私有內存空間,該區域是整個內存中較小的一塊。

  • 當線程正在執行一個Java方法時,PC計數器記錄的是正在執行的虛擬機字節碼的地址;當線程正在執行的一個Native方法時,PC計數器則爲空(Undefined)。

虛擬機棧

虛擬機棧,生命週期與線程相同,是Java方法執行的內存模型。每個方法(不包含native方法)執行的同時都會創建一個棧幀結構,方法執行過程,對應着虛擬機棧的入棧到出棧的過程。

棧幀(Stack Frame)結構
棧幀是用於支持虛擬機進行方法執行的數據結構,是屬性運行時數據區的虛擬機站的棧元素。見上圖, 棧幀包括:

  • 局部變量表 (locals大小,編譯期確定),一組變量存儲空間, 容量以slot爲最小單位。
  • 操作棧(stack大小,編譯期確定),操作棧元素的數據類型必須與字節碼指令序列嚴格匹配
  • 動態連接, 指向運行時常量池中該棧幀所屬方法的引用,爲了 動態連接使用。
    前面的解析過程其實是靜態解析;
    對於運行期轉化爲直接引用,稱爲動態解析。
  • 方法返回地址
    正常退出,執行引擎遇到方法返回的字節碼,將返回值傳遞給調用者
    異常退出,遇到Exception,並且方法未捕捉異常,那麼不會有任何返回值。
  • 額外附加信息,虛擬機規範沒有明確規定,由具體虛擬機實現。

異常(Exception)
Java虛擬機規範規定該區域有兩種異常:

  • StackOverFlowError:當線程請求棧深度超出虛擬機棧所允許的深度時拋出
  • OutOfMemoryError:當Java虛擬機動態擴展到無法申請足夠內存時拋出

本地方法棧

本地方法棧則爲虛擬機使用到的Native方法提供內存空間,而前面講的虛擬機棧式爲Java方法提供內存空間。有些虛擬機的實現直接把本地方法棧和虛擬機棧合二爲一,比如非常典型的Sun HotSpot虛擬機。

異常(Exception)
Java虛擬機規範規定該區域可拋出StackOverFlowError和OutOfMemoryError。

方法區

方法區主要存放的是已被虛擬機加載的類信息、常量、靜態變量、編譯器編譯後的代碼等數據。GC在該區域出現的比較少。

異常(Exception)
Java虛擬機規範規定該區域可拋出OutOfMemoryError。

運行時常量池
運行時常量池也是方法區的一部分,用於存放編譯器生成的各種字面量和符號引用。運行時常量池除了編譯期產生的Class文件的常量池,還可以在運行期間,將新的常量加入常量池,比較常見的是String類的intern()方法。

  • 字面量:與Java語言層面的常量概念相近,包含文本字符串、聲明爲final的常量值等。

  • 符號引用:編譯語言層面的概念,包括以下3類:

  1. 類和接口的全限定名
  2. 字段的名稱和描述符
  3. 方法的名稱和描述符
    但是該區域不會拋出OutOfMemoryError異常。

Java堆

Java堆,是Java虛擬機管理的最大的一塊內存,也是GC的主戰場,裏面存放的是幾乎所有的對象實例和數組數據。JIT編譯器有棧上分配、標量替換等優化技術的實現導致部分對象實例數據不存在Java堆,而是棧內存。

  • 從內存回收角度,Java堆被分爲新生代和老年代;這樣劃分的好處是爲了更快的回收內存;
  • 從內存分配角度,Java堆可以劃分出線程私有的分配緩衝區(Thread Local Allocation Buffer,TLAB);這樣劃分的好處是爲了更快的分配內存;

對象創建的過程是在堆上分配着實例對象,那麼對象實例的具體結構如下:

對於填充數據不是一定存在的,僅僅是爲了字節對齊。HotSpot VM的自動內存管理要求對象起始地址必須是8字節的整數倍。對象頭本身是8的倍數,當對象的實例數據不是8的倍數,便需要填充數據來保證8字節的對齊。該功能類似於高速緩存行的對齊。

另外,關於在堆上內存分配是併發進行的,虛擬機採用CAS加失敗重試保證原子操作,或者是採用每個線程預先分配TLAB內存.

異常(Exception)
Java虛擬機規範規定該區域可拋出OutOfMemoryError。

參考:
http://gityuan.com/2016/01/09/java-memory/

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