JVM學習筆記之四:分代垃圾回收

    

    如圖所示,在HotSpot虛擬機中共劃分有三個代:年輕代(young generation),年老代(old generation)和持久代(permanent generation)。實際上真正有意義的是年輕代和年老代,對象的生成與消亡都發生在這兩個區域。 java


    持久代(permanent generation)

    在開始介紹年輕代和年老代以前,先來講一說持久代吧。 網絡

    持久代的主要做用是存放java類等靜態化的信息,能夠看做是方法區的一部分。垃圾回收對持久代的影響並不大,只有某些須要動態生成類的應用才須要去關注這個區域的大小,能夠經過-XX:MaxPermSize=<N>進行設置 jvm

    持久代是個比較神奇的概念,應該是Hotspot虛擬機裏所特有的一個代。它是方法區的一部分,按常理不該該屬於堆。而且在經過jvm參數設定各個區域大小的時候,能夠很明顯的發現持久代和堆的大小是須要分別指定的,二者不是一個總體。可是網絡上鋪天蓋地的資料裏都把它歸屬於堆,對此我一直感到沒法理解,一種可能的解釋是在早期的Hotspot虛擬機中,持久代就是堆的一部分。若是有高人清楚這麼歸類的緣由,還望解惑。 優化


    年輕代(young generation)

    年輕代是JVM堆中最常發生垃圾回收的區域,全部對象都生成於此。 spa

    如上圖所示,年輕代通常能夠分紅三個區域,其中一個是Eden區,另外的兩個From和To都是Survivor區。通常新生成的對象都出如今Eden區,當Eden區被填滿時,全部通過垃圾回收還存活的對象將被複制到兩個Survivor區域中的一個,咱們假定是From區(兩個區域實際上沒有任何區別,From和To只是爲了更好的說明工做流程),當From區域也被填滿時,這個區域通過垃圾回收仍存活的對象將會被複制進入To區域,原From區域被清空,而且從Eden區過來的數據將直接進入To區域。當To區域也被填滿時,以前從From區域過來的那部分數據若是仍在活動,則將被放入年老代。
對象

    須要注意的是,兩個Survivor區域總有一個會是空的,而且Survivor是能夠被設置爲多個的。Survivor的個數越多,則對象在進入年老區以前要經歷的垃圾回收次數也越多。
生命週期


    年老代(old generation)

    在年輕代中經歷屢次垃圾回收後仍舊存活的對象,都將進入年老代。這個區域中的對象生命週期較長,當這個區域也被寫滿時,會觸發整個堆的垃圾回收。
虛擬機


    堆的垃圾回收

    堆的垃圾回收通常被分紅兩種,分別是Scavenge GC 和 Full GC。
工作流

    Scavenge GC只發生在年輕代,當Eden區域的空間被寫滿時觸發,觸發後執行的動做就是發生在年輕代中的故事,不在複述。這種垃圾回收的目的就是儘快的爲新生成的對象騰出空間,將生命週期較長的對象放入年老代。 io

    Full GC 對整個堆進行整理,當年老代或者持久代被寫滿時或者java程序中system.gc()被調用時會觸發。Full gc的執行會引發程序的短期暫停,所以如何合理有效的分配堆空間,減小Full gc的次數是JVM優化的一個重要內容。

相關文章
相關標籤/搜索