(五)年輕代以及他的垃圾回收算法

爲什麼要區分年輕代和老年代呢?

年輕代裏存放的大多數對象是短期存活的對象,需要用複製回收算法。老年代裏存放的對象是長期存活的對象,用的是標記-整理算法。所以才需要區分年輕代和老年代。

一種不太好的回收思路

思路:標記出哪些對象是可以被GC的,然後直接將那塊內存區域的對象進行GC。

這樣的話,對象會在內存中東一個西一個,造成大量的內存碎片。雖然所有的內存碎片加起來是很大的一塊內存,但是它們都是碎片式分散的,所以導致沒有一塊完整的足夠的內存區域來分配對象,從而造成內存浪費。

初步的複製回收算法

1.我們將新生代的內存切分爲兩塊

2.標記哪些對象是不能被GC的,將這些對象轉移到另一塊空白的內存區域,因此這些對象都可以緊湊的有序的排列在內存中,不存在內存碎片的問題。

3.一次性把原來使用的那塊內存中的垃圾對象全部清除掉,空出來一塊內存區域

4.兩塊內存區域這麼重複循環使用着

存在的問題:對內存的使用率太低了,假設我們給新生代分配1G的內存空間,實際上也就只有512MB的內存空間是可以用的

複製算法的優化:Eden和Survivor區

其實絕大多數對象是存活週期非常短的對象,可能一次新生代GC後,99%的對象都被垃圾回收了,可能也就1%的對象存活下來。由於這個特性,所以就設計了留10%的新生代內存空間來存放一次GC後存活的對象

將新生代內存分爲3塊區域,1個Eden區(佔80%的空間),2個Survivor區(每個Survivor區佔10%)。平時可以使用的,就是一個Eden和一個Survivor,相當於有90%得內存空間可以使用,而另一個Survivor區使用來存放上一次GC後存活的對象。

剛開始對象都是在Eden區中分配的,如果Eden快滿了,就觸發GC。此時會把Eden區中存活的對象一次性轉移到一塊空着的Survivor區,接着Eden區全部清空,然後再次分配新對象到Eden區。

如果下次再發生MinorGC,就會把Eden區和放着上次存活對象的Survivor區中的存活對象轉移到另一塊空的Survivor區中,再一次性把Eden區和之前使用的Survivor區全部清空。然後一直循環往復。

最大的好處是,垃圾回收性能好,無內存碎片,內存的使用率高。

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章