java 永久代_Java新生代、老生代和永久代详解
前言: 還是面試經常被q,小結一下
image.png
JVM中的堆一般分為三部分,新生代、老年代和永久代。
1 新生代
主要是用來存放新生的對象。一般占據堆空間的1/3,由于頻繁創建對象,所以新生代會頻繁觸發MinorGC進行垃圾回收。
新生代分為Eden區、ServivorFrom、ServivorTo三個區。
Eden區:Java新對象的出生地(如果新創建的對象占用內存很大則直接分配給老年代)。當Eden區內存不夠的時候就會觸發一次MinorGc,對新生代區進行一次垃圾回收。
ServivorTo:保留了一次MinorGc過程中的幸存者。
ServivorFrom: 上一次GC的幸存者,作為這一次GC的被掃描者。
當JVM無法為新建對象分配內存空間的時候(Eden區滿的時候),JVM觸發MinorGc。因此新生代空間占用越低,MinorGc越頻繁。
MinorGC采用復制算法。
2 老年代
老年代的對象比較穩定,所以MajorGC不會頻繁執行。
觸發MinorGC的條件:
1 在進行MajorGC之前,一般都先進行了一次MinorGC,使得有新生代的對象進入老年代,當老年代空間不足時就會觸發MajorGC。
2 當無法找到足夠大的連續空間分配給新創建的較大對象時,也會觸發MajorGC進行垃圾回收騰出空間。
MajorGC采用標記—清除算法(或者標記—整理算法)
MajorGC的耗時比較長,因為要先整體掃描再回收,MajorGC會產生內存碎片。為了減少內存損耗,一般需要合并或者標記出來方便下次直接分配。
當老年代也滿了裝不下的時候,就會拋出OOM。
永久代
指內存的永久保存區域,主要存放Class和Meta(元數據)的信息。
Class在被加載的時候元數據信息會放入永久區域,但是GC不會在主程序運行的時候清除永久代的信息。所以這也導致永久代的信息會隨著類加載的增多而膨脹,最終導致OOM。
注意: 在Java8中,永久代已經被移除,被一個稱為“元數據區”(元空間)的區域所取代。
元空間的本質和永久代類似,都是對JVM規范中方法區的實現。不過元空間與永久代之間最大的區別在于:元空間并不在虛擬機中,而是使用本地內存。因此默認情況下元空間的大小僅僅受本地內存的大小限制。類的元數據放入 native memory, 字符串池和類的靜態變量放入java堆中。 這樣可以加載多少類的元數據就不再由MaxPermSize控制, 而由系統的實際可用空間來控制。
MajorGC和FullGC的區別(這里參考1建議不要糾結這兩個概念的區別,而是應該專注于解決問題)
Full GC 是清理整個堆空間—包括年輕代和老年代。
Major GC 是清理老年代。
MinorGC 觸發機制
1 Eden區滿的時候,JVM會觸發MinorGC。
MajorGC 觸發機制
1 在進行MajorGC之前,一般都先進行了一次MinorGC,使得有新生代的對象進入老年代,當老年代空間不足時就會觸發MajorGC。
2 當無法找到足夠大的連續空間分配給新創建的較大對象時(如大數組),也會觸發MajorGC進行垃圾回收騰出空間。
Full GC觸發機制:
1 調用System.gc時,系統建議執行Full GC,但是不必然執行
2 老年代空間不足
3 方法區空間不足
4 通過Minor GC后進入老年代的平均大小大于老年代的可用內存
5 由Eden區、survivor space1(From Space)區向survivor space2(To Space)區復制時,
4 當永久代滿時也會引發Full GC,會導致Class、Method元信息的卸載。
虛擬機給每個對象定義了一個對象年齡(Age)計數器。如果對象在 Eden 出生并經過第一次 Minor GC 后仍然存活,并且能被 Survivor 容納的話,將被移動到 Survivor 空間中,并將對象年齡設為 1。對象在 Survivor 區中每熬過一次 Minor GC,年齡就增加 1 歲, 當它的年齡增加到一定程度(默認為 15 歲)時,就會被晉升到老年代中。對象晉升老年代的年齡閾值,可以通過參數 -XX:MaxTenuringThreshold (閾值)來設置。
總結
以上是生活随笔為你收集整理的java 永久代_Java新生代、老生代和永久代详解的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 《暗黑破坏神:不朽》安装量突破千万:官方
- 下一篇: “恐龙”发威 中国电影市场103天后单日