Jvm內存模型

java是在java虛擬機上運行,通常地你們講到的Java內存其實就是Jvm內存java

#1、內存模型 Java內存模型,每每是指Java程序在運行時內存的模型,而Java代碼是運行在Java虛擬機之上的,由Java虛擬機經過解釋執行(解釋器)或編譯執行(即時編譯器)來完成,故Java內存模型,也就是指Java虛擬機的運行時內存模型。程序員

做爲Java開發人員來講,並不須要像C/C++開發人員,須要時刻注意內存的釋放,而是全權交給虛擬機去管理,那麼有就必要了解虛擬機的運行時內存是如何構成的。運行時內存模型,分爲線程私有和共享數據區兩大類,其中線程私有的數據區包含程序計數器、虛擬機棧、本地方法區,全部線程共享的數據區包含Java堆、方法區,在方法區內有一個常量池。 輸入圖片說明數組

(1)線程私有區:緩存

  • 程序計數器,記錄正在執行的虛擬機字節碼的地址;
  • 虛擬機棧:方法執行的內存區,每一個方法執行時會在虛擬機棧中建立棧幀;
  • 本地方法棧:虛擬機的Native方法執行的內存區;

(2)線程共享區:數據結構

  • Java堆:對象分配內存的區域;
  • 方法區:存放類信息、常量、靜態變量、編譯器編譯後的代碼等數據;
    • 常量池:存放編譯器生成的各類字面量和符號引用,是方法區的一部分。

對於大多數的程序員來講,Java內存比較流行的說法即是堆和棧,這實際上是很是粗略的一種劃分,這種劃分的」堆」對應內存模型的Java堆,」棧」是指虛擬機棧,然而Java內存模型遠比這更復雜,想深刻了解Java的內存,仍是有必要明白整個內存模型。併發

#2、 詳細模型 運行時內存分爲五大塊區域(常量池屬於方法區,算做一塊區域),前面簡要介紹了每一個區域的功能,那接下來再詳細說明每一個區域的內容,Java內存整體結構圖以下: 輸入圖片說明優化

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

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

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

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

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

####異常(Exception)

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

  • StackOverFlowError:當線程請求棧深度超出虛擬機棧所容許的深度時拋出
  • OutOfMemoryError:當Java虛擬機動態擴展到沒法申請足夠內存時拋出 ##2.3 本地方法棧 本地方法棧則爲虛擬機使用到的Native方法提供內存空間,而前面講的虛擬機棧式爲Java方法提供內存空間。有些虛擬機的實現直接把本地方法棧和虛擬機棧合二爲一,好比很是典型的Sun HotSpot虛擬機。

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

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

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

對象建立的過程是在堆上分配着實例對象,那麼對象實例的具體結構以下: 輸入圖片說明

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

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

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

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

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

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

  • 字面量:與Java語言層面的常量概念相近,包含文本字符串、聲明爲final的常量值等。
  • 符號引用:編譯語言層面的概念,包括如下3類:
  • 類和接口的全限定名
  • 字段的名稱和描述符
  • 方法的名稱和描述符 可是該區域不會拋出OutOfMemoryError異常。
相關文章
相關標籤/搜索