1. 程式人生 > >垃圾回收器——垃圾回收演算法的具體實現

垃圾回收器——垃圾回收演算法的具體實現

垃圾回收器:

Serial收集器:

               採用複製演算法,是一種單執行緒的垃圾回收機制,是虛擬機器新生代預設情況下的首選收集器。        

             特點:與其他單執行緒收集器相比,簡單而高效。但是因為在垃圾回收過程中要中斷別的工作執行緒。



Parnew收集器:

                Serial收集器的多執行緒版本,是Server端模式下虛擬機器的首選的新生代收集器。

                目前只有它能與CMS收集器(第一個真正意義上的併發收集器)進行配合使用。


Parallel Scavenge收集器:

           使用的是複製演算法,並行的多執行緒新生代收集器,這個收集器的關注點是:吞吐量,

即             吞吐量=使用者程式碼所佔用CUP時間/(使用者程式碼所佔用的CUP時間+垃圾回收所佔用的CPU時間)。

        由於關注的是吞吐量,此垃圾收集器主要用於後臺運算量較大互動較少的虛擬機器。


SerialOld收集器:

              是Serial收集器的老年代版本,他是一個單執行緒的收集器,使用"標記——整理演算法"實現。主要是在Client模式下進行使用,如果在Server模式下有兩大用途:

                                                           1.配合Parallel Scavenge收集器使用

                                                           2.可以作為CMS收集器的備選預案,在Concurren Mark  Sweap 下使用。



ParallelOld收集器:

                               是ParallelScavenge的老年代版本,使用多執行緒的“標記——整理演算法”,在JDK1.6之前,如果新生代使用了Parallel Scavenge收集器,老年代只能使用SerialOld收集器。



CMS收集器:

                    CMS收集器是一種以獲取最短回收停頓時間為目標的收集器,因為現在很大一部分應用是部署在B/S伺服器上,

 追求的是響應速度,所以這一回收器主要用在Server端,主要實現的是“標記——清除演算法”。

CMS收集器回收垃圾的過程可以分為一下四個步驟:

                      1.初始標記,

                      2.併發標記,

                      3.重新標記,

                      4.併發清除。

其中初始標記和併發標記階段仍會短暫的暫停業務執行緒,

初始標記階段僅僅是進行標記GC Roots能直接關聯的物件,速度很快。

併發標記階段就是進行GC Roots Tracing的過程,

重新標記就是為了重新修正併發標記的過程因程式變動導致標記產生變動的那一部分物件。這個階段比初始標記稍長的一點,遠

遠小於併發標記。


          CMS收集器的優點:併發收集,低停頓。

                               缺點:

1. CMS收集器對CPU資源非常敏感,面向併發設計的程式對CPU資源都比較敏感。

 在進行併發階段,回收執行緒雖然不會停頓程式但是會佔用一部分執行緒(CPU資源),從而導致程式變慢,降低程式的吞吐量,

CMS預設開啟的回收執行緒是(CPU數量+3)/4,也就是在CUP數量超過四個時,回收執行緒佔用CPU資源25%不到,但是當CPU小

於4個時,如果CPU負載本來就比較大時,可能會導致吞吐量降低到50% 一下,這就讓人忍受不了了。

為了解決這個問題虛擬機器就提供了一種叫做“增量式併發收集器"(Incremental Concurrent Mark Sweap)——iCMS的CMS收集

器的變種,即在垃圾回收執行緒工作時,不在單獨佔用CPU時間,而是讓業務執行緒和回收執行緒搶佔CPU時間片 從而讓GC執行緒和使用者

執行緒交替執行, 但是目前版本中“iCMS”已被列為deprecated,不建議再使用。

2.CMS無法處理浮動垃圾

  CMS垃圾回收的時候,業務執行緒也會執行,這個時候業務執行緒產生的垃圾叫做浮動垃圾(Float garbage)。

  所以就導致了要預留一部分記憶體給浮動垃圾,這就導致了有可能記憶體使用率才到68%就要啟動垃圾回收程式,要是預留的記憶體

不足,則會出現Concurrent Mode Failure,然後就會啟動備用的收集器SerialOld收集器。

3.會出現記憶體碎片,

   CMS是基於“標記——清除演算法”,“標記——清除演算法”的缺點就是會出現碎片,導致可用的記憶體空間不連續。導致無法為

佔用記憶體較大的物件進行分配記憶體。

G1收集器:

                  相比於CMS收集器有了比較明顯的改進:

                    1.採用"標記——清理演算法",不會出現記憶體碎片。

                   2.是他能非常精確地控制停頓,既能讓使用者明確指定在一個M毫秒的時間內,消耗在垃圾收集的時間不能超過N毫秒,這幾乎是實時JAVA(RTSJ)垃圾收集器的特徵。

                   G1收集器可以在基本不犧牲吞吐量的情況下完成低停頓的記憶體回收,這是由於它能夠極力地避免全區域的垃圾收集,之前的整個垃圾收集進行的範圍是整個新生代或者老年代,而G1將整個JAVA堆(包括新生代和老年代)劃分為多個大小固定獨立的區域,並且跟蹤這些區域裡面垃圾的堆積程度,在後臺維護一個優先順序列表,然後在允許的垃圾回收時間內,優先回收垃圾堆積最多的記憶體區域(Garage First的由來),區域的劃分和優先順序的區域回收,保證了G1收集器在有限的時間內可以獲得最高的收集效率。


垃圾收集的相關引數可以自行進行百度。