天天看點

JVM的新生代、老年代、MinorGC、MajorGC(Full GC)JVM的新生代、老年代、MinorGC、MajorGC

JVM的新生代、老年代、MinorGC、MajorGC

參考資料:

http://blog.csdn.net/flamezyg/article/details/44673951

http://www.blogjava.net/ldwblog/archive/2013/07/24/401919.html

http://www.360doc.com/content/12/1023/16/9615799_243296263.shtml

    JVM中的堆,一般分為三大部分:新生代、老年代、永久代:

JVM的新生代、老年代、MinorGC、MajorGC(Full GC)JVM的新生代、老年代、MinorGC、MajorGC

    一:新生代:主要是用來存放新生的對象。一般占據堆的1/3空間。由于頻繁建立對象,是以新生代會頻繁觸發MinorGC進行垃圾回收。

         新生代又分為 Eden區、ServivorFrom、ServivorTo三個區。

         Eden區:Java新對象的出生地(如果新建立的對象占用記憶體很大,則直接配置設定到老年代)。當Eden區記憶體不夠的時候就會觸發MinorGC,對新生代區進行一次垃圾回收。

         ServivorTo:保留了一次MinorGC過程中的幸存者。

         ServivorFrom:上一次GC的幸存者,作為這一次GC的被掃描者。

         MinorGC的過程:MinorGC采用複制算法。首先,把Eden和ServivorFrom區域中存活的對象複制到ServicorTo區域(如果有對象的年齡以及達到了老年的标準,則指派到老年代區),同時把這些對象的年齡+1(如果ServicorTo不夠位置了就放到老年區);然後,清空Eden和ServicorFrom中的對象;最後,ServicorTo和ServicorFrom互換,原ServicorTo成為下一次GC時的ServicorFrom區。

JVM的新生代、老年代、MinorGC、MajorGC(Full GC)JVM的新生代、老年代、MinorGC、MajorGC

    二:老年代:主要存放應用程式中生命周期長的記憶體對象。

    老年代的對象比較穩定,是以MajorGC不會頻繁執行。在進行MajorGC前一般都先進行了一次MinorGC,使得有新生代的對象晉身入老年代,導緻空間不夠用時才觸發。當無法找到足夠大的連續空間配置設定給新建立的較大對象時也會提前觸發一次MajorGC進行垃圾回收騰出空間。

    MajorGC采用标記—清除算法:首先掃描一次所有老年代,标記出存活的對象,然後回收沒有标記的對象。MajorGC的耗時比較長,因為要掃描再回收。MajorGC會産生記憶體碎片,為了減少記憶體損耗,我們一般需要進行合并或者标記出來友善下次直接配置設定。

     當老年代也滿了裝不下的時候,就會抛出OOM(Out of Memory)異常。

    三:永久代

    指記憶體的永久儲存區域,主要存放Class和Meta(中繼資料)的資訊,Class在被加載的時候被放入永久區域. 它和和存放執行個體的區域不同,GC不會在主程式運作期對永久區域進行清理。是以這也導緻了永久代的區域會随着加載的Class的增多而脹滿,最終抛出OOM異常。

    在Java8中,永久代已經被移除,被一個稱為“中繼資料區”(元空間)的區域所取代。

    元空間的本質和永久代類似,都是對JVM規範中方法區的實作。不過元空間與永久代之間最大的差別在于:元空間并不在虛拟機中,而是使用本地記憶體。是以,預設情況下,元空間的大小僅受本地記憶體限制。類的中繼資料放入 native memory, 字元串池和類的靜态變量放入java堆中. 這樣可以加載多少類的中繼資料就不再由MaxPermSize控制, 而由系統的實際可用空間來控制.

    采用元空間而不用永久代的幾點原因:(參考:http://www.cnblogs.com/paddix/p/5309550.html)

  1、為了解決永久代的OOM問題,中繼資料和class對象存在永久代中,容易出現性能問題和記憶體溢出。

  2、類及方法的資訊等比較難确定其大小,是以對于永久代的大小指定比較困難,太小容易出現永久代溢出,太大則容易導緻老年代溢出(因為堆空間有限,此消彼長)。

  3、永久代會為 GC 帶來不必要的複雜度,并且回收效率偏低。

  4、Oracle 可能會将HotSpot 與 JRockit 合二為一。

總結下Minor GC 和Full GC 的觸發條件

Minor GC觸發條件:當Eden區滿時,觸發Minor GC。

Full GC觸發條件:

(1)調用System.gc時,系統建議執行Full GC,但是不必然執行

(2)老年代空間不足

(3)方法去空間不足

(4)通過Minor GC後進入老年代的平均大小大于老年代的可用記憶體

(5)由Eden區、From Space區向To Space區複制時,對象大小大于To Space可用記憶體,則把該對象轉存到老年代,且老年代的可用記憶體小于該對象大小

--------------------- 本文來自 逸辰杳 的CSDN 部落格 ,全文位址請點選:https://blog.csdn.net/YHYR_YCY/article/details/52566105?utm_source=copy