1. 程式人生 > >jvm(1)---java記憶體模型

jvm(1)---java記憶體模型

jvm主要由三個子系統構成:類載入子系統,執行時資料區(記憶體模型),執行引擎

執行時資料區主要包括:

1.本地方法棧:登記native方法,執行時載入本地方法庫

2.程式計數器:就是一個指標,用來儲存指向下一條執行指令的地址,也就是即將要執行的指令程式碼,是一個非常小得空間,可以忽略不計。

3.java棧:java執行緒執行方法的記憶體模型,一個執行緒對應一個棧,每個方法在執行時都會建立一個棧幀,用於儲存區域性變量表(引用),運算元棧,動態連結,方法出口等資訊,不存在垃圾回收問題,生命週期和執行緒一致,執行緒結束該棧就釋放。可以通過-Xss來設定棧空間。

4.方法區:類的所有欄位和方法位元組碼,以及一些特殊的方法,建構函式,介面定義,所有定義的方法的資訊都存放在這。此外還包括靜態變數,常量,執行時常量池

5.java堆:虛擬機器啟動時建立,用於存放物件例項,幾乎所有的物件都在堆上面分配記憶體,當物件無法在該空間申請到記憶體就會丟擲OutMemoryError異常,同時也是垃圾回收器主要管理的區域,可以通過-Xmx/Xms來設定最大/最小堆

 其中1.2.3都是執行緒私有,4.5執行緒共享

 

執行緒私有java棧圖解:

 

java堆詳解:

新生代:類誕生、成長、消亡的區域,一個類在這裡產生,應用,最後被垃圾回收器收集,結束生命。
新生代分為兩部分: 伊甸園區(Eden space:亞當,夏娃造人,這名字取得還是很有意義的)和倖存者區(Survivor pace) ,所有的類都是在伊甸園被new出來的。倖存區有兩個: 0區(Survivor 0 space(From))和1區(Survivor 1 space(To))。當伊甸園的空間用完時,程式又需要建立物件,JVM的垃圾回收器將對伊甸園區進行垃圾回收(Minor GC),將伊甸園區中的不再被其他物件所引用的物件進行銷燬。然後將伊甸園中的剩餘物件移動到倖存From。若幸From也滿了,再對該區進行垃圾回收,然後移動到To。From到To操作一次,還存在To中的物件就相當於長了一歲,預設是15歲,如果到了15歲都還存在有引用,那麼就放入老年代,可以用過-XX:MaxTenuringThreshold來設定這個年齡

老年代:新生代經過多次GC仍然存活的物件移動到老年區。若老年區也滿了,那麼這個時候將產生FullGC,進行老年區的記憶體清理。若老年區執行了Full GC之後發現依然無法進行物件的儲存,就會產生OOM異常“OutOfMemoryError”。可以同過減少FullGC來提高jvm效能

永久代(元資料):jdk1.8元資料區取代了永久代,本質和永久代類似,都是對JVM規範中方法區的實現,區別在於元資料區並不在虛擬機器中,而是使用本地實體記憶體,永久代在虛擬機器中,永久代邏輯結構上屬於堆,但是物理上不屬於堆,堆大小=新生代+老年代。元資料區也有可能發生OutOfMemory異常。
Jdk1.6及之前: 有永久代, 常量池在方法區
Jdk1.7:有永久代,但已經逐步“去永久代”,常量池在堆
Jdk1.8及之後: 無永久代,常量池在元空間
元資料區的動態擴充套件,預設–XX:MetaspaceSize值為21MB的高水位線。一旦觸及則Full GC將被觸發並解除安裝沒有用的類(類對應的類載入器不再存活),然後高水位線將會重置。新的高水位線的值取決於GC後釋放的元空間。如果釋放的空間少,這個高水位線則上升。如果釋放空間過多,則高水位線下降。

&n