JVM內存結構與內存模型

1、 Jvm內存結構

模塊分解數組

1. 程序計數器(線程私有)

(1) 是什麼?

    程序計數器是當前線程所執行的字節碼的行號指示器。緩存

(2) 做用?

    字節碼解釋器經過改變這個計算器的值來選擇下一條須要執行的字節碼指令,分支,循環,跳轉,異常處理,線程恢復,若是執行的是Native方法,這個計算器的值則爲空併發

2. Java虛擬機棧(線程私有)

(1) 是什麼

    Java虛擬機棧描述的是Java方法執行的內存模型:每一個方法在執行的同時都會建立一個棧幀,每一個方法從調用直至執行完成的過程,就對應着一個棧幀在虛擬機棧中入棧到出棧的過程。post

(2) 組成

① 局部變量表

    存放了編譯期可知的基本類型、對象引用類型和returnAddress類型(指向一條字節碼指令的地址。即程序就是存儲在方法區的字節碼指令,而 returnAddress 類型的值就是指向特定指令內存地址的指針)this

② 操做數棧

    操做數是一個後入先出棧,JVM全部的操做碼都是對操做數棧上的數據進行操做,對於每個方法的調用,JVM會創建一個操做數棧,以供計算使用。操作系統

    例如 a = b + c 的字節碼執行過程當中操做數棧以及局部變量表的變化以下圖所示。線程

    局部變量表中存儲着a、b、c 三個局部變量,首先將b和c分別入棧

③ 動態連接

    運行期間轉化爲直接引用,就稱爲動態連接。Class字節碼的常量持中存有大量的符號引用,在運行期纔將符號引用變成直接引用(也就是指向數據),能夠是方法或者字段的引用。3d

④ 方法出口

    即本方法執行後下一步指令的地址,方法正常退出時,調用者PC計數器的值就能夠做爲返回地址,異常退出時,返回地址是要經過異常處理器來肯定。指針

3. 本地方法棧(線程私有)

(1) 是什麼?

    保存native方法進入區域的地址cdn

4. Java堆(線程共享)

(1) 是什麼?

    全部的對象實例以及數組都要在堆上分配。是垃圾收集器管理的主要區域。

(2) 分區

① 新生代: Eden區、Survivor From區、Survivor To區
② 老年代

5. 方法區(線程共享)

(1) 是什麼

    方法區用於存儲已被虛擬機加載的類信息、方法、常量、靜態成員變量、JIT(即時編譯器)編譯後的代碼等數據,在類加載時分配。

(2) 也叫非堆,分配在元空間

    元空間:類的元數據,如方法數據、方法信息(字節碼,棧和變量大小)、運行時常量池、已肯定的符號引用和虛方法表等方法區的數據,保存在本地內存區域(堆外內存)

6. 運行時常量池(線程共享)

(1) 是什麼

    運行時常量池用於存放編譯期和運行期生成的各類字面量和符號引用。這部份內容將在類加載後進入方法區的運行時常量池中存放。屬於方法區的一部分

(2) 字面量和符號引用

    字面量:1.字符串;2.基本類型值;3.final常量     符號引用:1.類和方法的全限定名;2.字段的名稱和描述符;3.方法的名稱

2、 Jvm內存模型

1. 定義

    因爲不一樣平臺內存模型的差別,有可能致使程序在不一樣平臺的併發訪問出錯。Java內存模型(Java Memory Model,JMM)是屏蔽各類硬件和操做系統的內存訪問差別,以實現讓Java程序在各類平臺下都能達到一致的內存訪問效果。

2. 具體操做

    定義程序中各個變量的訪問規則,即在虛擬機中將變量存儲到內存和從內存中取出變量的底層細節。
    此處的變量是指實例字段,靜態字段和構成數組對象的元素,不包括局部變量與方法參數

3. 主內存和工做內存

    Jvm內存模型規定全部的變量都存儲在主內存中,每條線程還有本身的工做內存,工做內存保存了被該線程使用到的變量的主內存副本拷貝。

4. synchronization、final、volatile

(1) synchronization

① 互斥

    對於一個monitor對象,當被一個線程持有,其餘線程只能等待

② 可見性

    保證了線程在同步代碼塊期間寫入動做,對於後續進入該代碼塊的線程是可見的(持有相同monitor對象的線程)。
    當前線程釋放monitor對象,做用是把cpu緩存數據刷新到主內存中;其餘線程進入該代碼塊時,須要獲取monitor對象,會使cpu緩存失效,從而使變量從主內存中從新加載。

③ 禁止指令重排序

(2) final

① 禁止指令重排序
② 可見性

    被final修飾的字段在構造器中一旦初始化完成,而且構造器沒有把」this」引用傳遞出去(「this」引用逃逸是一件很危險的事情,其餘線程有可能經過這個引用訪問到」初始化了一半」的對象),那麼其餘線程就能看見final字段的值。

(3) volatile

① 可見性
② 禁止指令重排序

5. 示例

(1) 重排序

(2) 可見性

(3) 互斥性

做者:陶章好
連接:juejin.im/post/5d6281… 來源:掘金 著做權歸做者全部。商業轉載請聯繫做者得到受權,非商業轉載請註明出處。

相關文章
相關標籤/搜索