簡述垃圾回收算法與垃圾回收器

垃圾收集算法算法

  1. 標記-清除算法
  2. 複製算法
  3. 標記-整理算法
  4. 分代收集算法

標記-清除算法:多線程

  • 首先標記出全部須要回收的對象,在標記完成後統一回收全部被標記的對象。
  • 它的主要不足有兩個:一個是效率問題,標記和清除兩個過程的效率都不高;另外一個是空間問題,標記清除以後會產生大量不連續的內存碎片,致使以後程序運行時須要分配比較大,沒法找到足夠大連續的空間。

複製算法:併發

  • 爲了解決效率問題,它將可用內存按容量劃分爲大小相等的兩塊,每次只使用其中的一塊。每次只使用其中的一塊。當這一塊的內存用完了,就將還存活着的對象複製到另一塊上面,而後再把已使用過的內存空間一次清理掉。
  • 代價是將內存縮小爲了原來的一半

標記-整理算法:性能

  • 爲解決對象存活率高時進行較多的複製操做,以及浪費一半內存空間就須要有額外的空間進行分配擔保
  • 標記過程仍然與「標記-清除」算法同樣,讓全部存活的對象都向一端移動,而後直接清理掉端邊界之外的內存。

分代收集算法:線程

  • 在新生代中,每次垃圾收集時都發現有大批對象死去,只有少許存活,那就選用複製算法,只須要付出少許存活對象的複製成本就能夠完成收集。
  • 在老年代中,由於對象存活率高、沒有額外空間對它進行分配擔保,就必須使用「標記—清理」或者「標記—整理」算法來進行回收。

2.垃圾收集器3d

若是兩個垃圾收集器之間存在連線,說明能夠搭配使用。對象

1.Serial收集器blog

 

特性:簡單而高效,該收集器沒有線程交互的開銷,能夠獲取最高的單線程收集效率。排序

基本原理:單線程,在進行垃圾收集時,必須暫停其餘全部的工做線程,直到它收集結束。內存

使用場景:在Client模式下,分配給虛擬機管理的內存通常來講不會很大,收集幾十兆甚至一兩百兆的新生代,停頓時間徹底能夠接受。

2.ParNew收集器

特性:除了Serial收集器之外,只有ParNew收集器能夠CMS收集器配合。

基本原理:Serial收集器的多線程版本

使用場景:在Server模式下的虛擬機中首選的新生代收集器。

3.Parallel Savenge收集器(吞吐量優先)

特性:縮短停頓時間是以犧牲吞吐量和新生代空間來換取的:新生代空間變小,垃圾回收變得頻繁,致使吞吐量降低。

        能夠經過一個開關參數打開 GC 自適應的調節策略(GC Ergonomics),就不須要手工指定新生代的大小(-Xmn)、Eden 和 Survivor 區的比例、晉升老年代對象年齡等細節參數了。虛擬機會根據當前系統的運行狀況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大的吞吐量。

基本原理:與 ParNew 同樣是多線程收集器,其它收集器目標是儘量縮短垃圾收集時用戶線程的停頓時間,而它的目標是達到一個可控制的吞吐量,所以它被稱爲「吞吐量優先」收集器。

使用場景:停頓時間越短就越適合須要與用戶交互的程序,良好的響應速度能提高用戶體驗。而高吞吐量則能夠高效率地利用 CPU 時間,儘快完成程序的運算任務,適合在後臺運算而不須要太多交互的任務。

4.Serial Old 收集器

基本原理:Serial Old是Serial收集器的老年代版本,單線程收集器,使用「標記-整理」算法

使用場景:主要意義也是在於給Client模式下的虛擬機使用。若是在Server模式下,那麼它主要還有兩大用途:一種用途是在JDK 1.5以及以前的版本中與Parallel Scavenge收集器搭配使用,另外一種用途就是做爲CMS收集器的後備預案,在併發收集發生用。

5.Parallel Old收集器

特性:除了Serial收集器之外,只有ParNew收集器能夠CMS收集器配合。

基本原理:Parallel Old是Parallel Scavenge收集器的老年代版本,使用多線程和「標記-整理」算法。

使用場景:在注重吞吐量以及CPU資源敏感的場合,均可以優先考慮Parallel Scavenge加Parallel Old收集器。

6.CMS收集器

  • 初始標記:僅僅只是標記一下GC Roots能直接關聯到的對象,速度很快,須要停頓。
  • 併發標記:進行GC RootsTracing的過程
  • 從新標記:是爲了修正併發標記期間因用戶程序繼續運做而致使標記產生變更的那一部分對象的標記記錄,須要停頓。
  • 併發清除

        因爲整個過程當中耗時最長的併發標記和併發清除過程收集器線程均可以與用戶線程一塊兒工做,因此,從整體上來講,CMS收集器的內存回收過程是與用戶線程一塊兒併發執行的。

有如下3個明顯的缺點:

  • CMS收集器對CPU資源很是敏感。在併發階段,它雖然不會致使用戶線程停頓,可是會由於佔用了一部分線程(或者說CPU資源)而致使應用程序變慢,總吞吐量會下降。
  • 沒法處理浮動垃圾,可能出現 Concurrent Mode Failure。浮動垃圾是指併發清除階段因爲用戶線程繼續運行而產生的垃圾,這部分垃圾只能到下一次 GC 時才能進行回收。因爲浮動垃圾的存在,所以須要預留出一部份內存,意味着 CMS 收集不能像其它收集器那樣等待老年代快滿的時候再回收。若是預留的內存不夠存放浮動垃圾,就會出現 Concurrent Mode Failure,這時虛擬機將臨時啓用 Serial Old 來替代 CMS。
  • CMS是一款基於「標記—清除」算法實現的收集器。空間碎片過多時,將會給大對象分配帶來很大麻煩,每每會出現老年代還有很大空間剩餘,可是沒法找到足夠大的連續空間來分配當前對象,不得不提早觸發一次Full GC。

7.G1收集器

G1(Garbage-First),它是一款面向服務端應用的垃圾收集器,在多 CPU 和大內存的場景下有很好的性能。HotSpot 開發團隊賦予它的使命是將來能夠替換掉 CMS 收集器。

堆被分爲新生代和老年代,其它收集器進行收集的範圍都是整個新生代或者老年代,而 G1 能夠直接對新生代和老年代一塊兒回收。

G1 把堆劃分紅多個大小相等的獨立區域(Region),新生代和老年代再也不物理隔離。

        經過引入 Region 的概念,從而將原來的一整塊內存空間劃分紅多個的小空間,使得每一個小空間能夠單獨進行垃圾回收。這種劃分方法帶來了很大的靈活性,使得可預測的停頓時間模型成爲可能。經過記錄每一個 Region 垃圾回收時間以及回收所得到的空間(這兩個值是經過過去回收的經驗得到),並維護一個優先列表,每次根據容許的收集時間,優先回收價值最大的 Region。

        每一個 Region 都有一個 Remembered Set,用來記錄該 Region 對象的引用對象所在的 Region。經過使用 Remembered Set,在作可達性分析的時候就能夠避免全堆掃描。

若是不計算維護 Remembered Set 的操做,G1 收集器的運做大體可劃分爲如下幾個步驟:

  • 初始標記
  • 併發標記
  • 最終標記:爲了修正在併發標記期間因用戶程序繼續運做而致使標記產生變更的那一部分標記記錄,虛擬機將這段時間對象變化記錄在線程的 Remembered Set Logs 裏面,最終標記階段須要把 Remembered Set Logs 的數據合併到 Remembered Set 中。這階段須要停頓線程,可是可並行執行。
  • 篩選回收:首先對各個 Region 中的回收價值和成本進行排序,根據用戶所指望的 GC 停頓時間來制定回收計劃。此階段其實也能夠作到與用戶程序一塊兒併發執行,可是由於只回收一部分 Region,時間是用戶可控制的,並且停頓用戶線程將大幅度提升收集效率。

具有以下特色:

  • 空間整合:總體來看是基於「標記 - 整理」算法實現的收集器,從局部(兩個 Region 之間)上來看是基於「複製」算法實現的,這意味着運行期間不會產生內存空間碎片。
  • 可預測的停頓:能讓使用者明確指定在一個長度爲 M 毫秒的時間片斷內,消耗在 GC 上的時間不得超過 N 毫秒。
相關文章
相關標籤/搜索