JVM的邏輯記憶體模型圖 [邏輯記憶體模型圖] JVM內部分區 其實JVM內部不僅僅只有棧和堆 包括 程式計數器 、 Java 虛擬機棧 、本地方法棧、Java 堆、方法區等 1. 程式計數器 線程私有,較小的記憶體空間,如果線程正在執行的是一個Java 方法,這個計數器記錄的是正在執行的虛擬機位元組 碼指 ...
JVM的邏輯記憶體模型圖
[邏輯記憶體模型圖]
-----
JVM內部分區
其實JVM內部不僅僅只有棧和堆
包括 程式計數器 、 Java 虛擬機棧 、本地方法棧、Java 堆、方法區等
1. 程式計數器
線程私有,較小的記憶體空間,如果線程正在執行的是一個Java 方法,這個計數器記錄的是正在執行的虛擬機位元組
碼指令的地址;如果正在執行的是Natvie 方法,這個計數器值則為空(Undefined)。此
記憶體區域是唯一一個在Java 虛擬機規範中沒有規定任何OutOfMemoryError 情況的區域。
2. Java 虛擬機棧(棧區)
線程私有,每個方法被執行的時候都會同時創建一個棧幀用於存儲局部變數表、操作棧、動態
鏈接、方法出口等信息。每一個方法被調用直至執行完成的過程,就對應著一個棧幀在
虛擬機棧中從入棧到出棧的過程。
3.本地方法棧
與虛擬機棧所發揮的作用是非常相似的,區別不過是虛擬機棧為虛擬機執行Java 方法(也就是位元組碼)服務,
而本地方法棧則是為虛擬機使用到的Native 方法服務,有的虛擬機(譬如Sun HotSpot 虛擬機)直接就把本地方法棧和虛擬機棧合二為一。
與虛擬機棧一樣,本地方法棧區域也會拋出StackOverflowError 和OutOfMemoryError
4.Java 堆(堆區)
線程共用,此記憶體區域的唯一目的就是創建並存放對象實例,也是GC區。分代收集演算法:記憶體區大概分為新生代,老年代,永久代。
新生代從Eden區創建,複製到Survivor區(2個 from 和 to)。 GC分為minor GC 和 Full GC ,
minor GC: Eden滿了就觸發minor GC,minorGC會將Eden區仍然存活的會複製到ToSurvivor
,FromSurvivor一部分複製到老年代,一部分複製到ToSurvivor,此時原Eden和From的數據清空,from和to互換,這樣的過程直到To被填滿,複製到老年代。
FullGC:(1)年老代記憶體不足;(2)持久代記憶體不足;(3)統計得到的Minor GC晉升到舊生代的平均大小大於舊生代的剩餘空間(4)調用System.gc()方法的時候,
5. 方法區(類級/靜態)
線程共用,存儲已被虛擬機載入的類信息、常量、靜態變數、即時編譯器編譯後的代碼等數據。
雖然Java 虛擬機規範把方法區描述為堆的一個邏輯部分,但是它別名叫做Non-Heap(非堆)
即“永久代”,不進行GC,只是針對常量池的回收和對類型的卸載
運行時常量池:是方法區的一部分,Class常量池存放編譯期生成的各種字面量和符號引用,
運行時常量池相對於Class 文件常量池的另外一個重要特征是具備動態性,運行期間也可能將新的常量放入池中,這種特性被開發
人員利用得比較多的便是String 類的intern() 方法(這個方法會首先檢查字元串池中是否有”ab”這個字元串,如果存在則返回這個字元串的引用,
否則就將這個字元串添加到字元串常量池中,然會返回這個字元串的引用,這可以實現字元串的"= ="比較。new String 不進入常量池,直接賦值會進入常量池)。