JVM垃圾回收——新生代,老年代,永久代,Minor GC,Full GC
參考資料:
- 《深入理解Java虛擬機器》——周志明
- https://blog.csdn.net/u010796790/article/details/52213708
- https://blog.csdn.net/lirenzuo/article/details/77749925
- https://www.cnblogs.com/ygj0930/p/6522828.html
周志明先生,在《深入理解Java虛擬機器》一書中曾提到:程式計數器,虛擬機器棧,本地方法棧這3個區域是執行緒私有的,隨執行緒而生,隨執行緒而滅,這幾個區域就不需要過多考慮回收的問題,因為方法結束或者執行緒結束時,記憶體就自然跟著回收了。主要討論Java堆和方法區的回收。(Java堆和方法區是《Java虛擬機器規範》的術語)
Java堆通常分為新生代,老年代。永久代,實際上就是方法區。
【方法區】是JVM的一種規範,存放類資訊,常量,靜態變數,即時編譯後的程式碼等。
【永久代】是HotSpot的一種具體實現,實際上指的就是方法區,或者說用永久代來實現方法區。對於其他虛擬機器來說是不存在永久代的概念的。
新生代:
對於新生代而言,無論是使用哪一種垃圾收集器(JDK1.6之前新生代的垃圾收集器有三種:Serial,ParNew,Parallel Scavenge)採用的都是複製收集演算法。
JDK1.6中,新生代與老年代的比例的值為 1:2 ( 該值可以通過引數 –XX:NewRatio 來指定 ),新生代又可細分為:Eden、From Survivor、To Survivor三個區(8:1:1),也就是說新生代中可用記憶體空間為整個新生代容量的90%,有10%的記憶體被浪費。
Eden:新物件的出生地。
From Survivor:上一次GC的倖存者,作為這一次GC的被掃描者。
To Survivor:保留MinorGC過程中的倖存者。
【MinorGC的觸發條件】:當Eden區記憶體不足的時候,虛擬機器將進行一次MinorGC。Survivor區記憶體不足不會觸發MinorGC。MinorGC之後,可能會與一些新生代的物件年齡滿足進入老年代,老年代的佔用會有所升高。
MinorGC的過程:MinorGC採用複製演算法。首先,把Eden和From Survivor區域中存活的物件複製到To Survivor區域,同時把這些物件的年齡+1(預設情況下15歲就直接送到老年代了,晉升老年代的閾值可以通過-XX:MaxTenuringThreshold設定);然後,清空Eden和From Survivor中的物件;最後,To Survivor和From Survivor互換,原To Survivor成為下一次GC時的From Survivor區。
老年代:
主要存放程式中年齡較大和需要佔用大量連續記憶體空間的物件。老年代的物件比較穩定,所以MajorGC/Full GC執行的頻率較低。一般都是在空間不足的時候才會執行MajorGC/Full GC。
JDK1.6之前老年代的垃圾收集器Serial Old,Parallel Old採用的是標記—整理演算法,CMS採用的標記—清除演算法。標記—清除演算法會產生大量的記憶體碎片。
【新生代的物件進入老年代的情況】:
- 設定了-XX:PretenureSizeThreshold3M 引數,那麼大於3M的物件就會直接就進入老年代,這樣做的目的是避免在Eden區以及兩個Survivor區之間發生大量的記憶體複製。(只對於Serial收集器和ParNew兩款收集器有效)
- 長期存活的物件將進入老年代:對於在Survivor區中每熬過一次Minor GC,年齡就增加1歲,當它的年齡增加到一定程度,就會晉升到老年代中。(預設15歲,可以通過-XX:MaxTenuringThreshold設定)
- 如果在Survivor空間中相同年齡所有物件物件大小的總和大於Survivor空間的一半,年齡大於或等於該年齡的物件就可以直接進入老年代,無須等到MaxTenuringThreshold要求的年齡。
- 空間分配擔保機制:當Minor GC時,新生代存活的物件大於Survivor的大小時,這時一個Survivor裝不下它們,那麼它們就會進入老年代。
永久代:
HotSpot中對於JVM規範中方法區的實現,指記憶體的永久儲存區域,主要存放Class和Meta(後設資料)的資訊,Class在被載入的時候被放入永久區域。
在Java8中,永久代已經被移除,被一個稱為“後設資料區”(元空間)的區域所取代。
元空間的本質和永久代類似,都是對JVM規範中方法區的實現。不過元空間與永久代之間最大的區別在於:元空間並不在虛擬機器中,而是使用本地記憶體
Full GC:
關於Major GC,如果我們簡單理解的話,Major GC和Full GC通常情況下可以認為是等價的。主要是發生在老年代GC,出現Major GC/Full GC,通常情況下伴隨著至少一次的Minor GC(並不是絕對的),Major GC/Full GC的速度一般比Minor GC慢10倍以上。
【Full GC的觸發條件】:
- 當準備要觸發一次Minor GC時,如果發現統計資料說之前Minor GC的平均晉升大小比目前老年代剩餘的空間大,則不會觸發Minor GC而是轉為觸發Full GC(因為HotSpot VM的GC裡,除了CMS的concurrent collection之外,其它能收集老年代的GC都會同時收集整個GC堆,包括新時代,所以不需要事先觸發一次單獨的Minor GC);
- 如果有永久代的話,要在永久代分配空間但已經沒有足夠空間時,也要觸發一次Full GC;(Java虛擬規範中並不要求虛擬機器在方法區實現垃圾收集,而且在方法區中進行垃圾收集的“價效比”較低。在大量使用頻繁自定義ClassLoader的場景都需要虛擬機器具備類解除安裝的功能,以保證永久代不會溢位。)
- System.gc()、heap dump帶GC,預設也是觸發Full GC。
相關文章
- JVM 系列文章之 Full GC 和 Minor GCJVMGC
- [Inside HotSpot] Serial垃圾回收器 (二) Minor GCIDEHotSpotGC
- [Inside HotSpot] Serial垃圾回收器Full GCIDEHotSpotGC
- 總結Minor GC、Full GC觸發條件GC
- 聊聊JVM的垃圾回收機制GCJVMGC
- 秋招乾貨 - JVM 垃圾回收(GC)JVMGC
- jvm hotspot的minor major full gc之間的關係,以及哪些情況下會觸發full gcJVMHotSpotGC
- 【JVM第八篇--垃圾回收】GC和GC演算法JVMGC演算法
- JVM學習(二)——GC垃圾回收機制JVMGC
- GC垃圾回收器GC
- Unity GC垃圾回收UnityGC
- GC 分代回收 - 垃圾收集器GC
- java學習筆記-4 JVM垃圾回收(GC)Java筆記JVMGC
- JVM - 方法區(永久代)的垃圾回收JVM
- Full GC (Metadata GC Threshold)GC
- 十種GC垃圾回收器GC
- .Net平臺的GC垃圾回收GC
- 託管堆和垃圾回收(GC)GC
- JVM必備基礎知識(三)-- GC垃圾回收機制JVMGC
- jvm:記憶體模型、記憶體分配及GC垃圾回收機制JVM記憶體模型GC
- JDK 18 GC垃圾回收機制比較JDKGC
- jvm的新生代和老年代簡介JVM
- 關於jvm的永久代會發生垃圾垃圾回收嗎?進來便知JVM
- 【Android面試-Java-V05】Java GC 垃圾回收Android面試JavaGC
- 為什麼GC(垃圾回收)必須stop-the-world?GC
- (七)永久代(方法區)的垃圾回收
- jvm系列(三)GC演算法 垃圾收集器JVMGC演算法
- 垃圾回收演算法|GC標記-清除演算法演算法GC
- 觸發JVM進行Full GC的情況及應對策略JVMGC
- JVM 判斷物件已死,實踐驗證GC回收JVM物件GC
- 擴容新生代為什麼能夠提高GC的效率GC
- 深入理解Java的垃圾回收機制(GC)實現原理JavaGC
- JVM之GC趣解JVMGC
- JVM的GC日誌JVMGC
- JVM GC日誌解析JVMGC
- [JVM]垃圾回收JVM
- JVM垃圾回收JVM
- 什麼是垃圾蒐集(GC)?為什麼要有GC呢?GC