垃圾收集器與內存分配策略---垃圾收集器

垃圾收集器

  收集算法是內存回收的方法論,垃圾收集器是內存回收的具體實現。java

  以上是 HotSpot 虛擬機中的 7 個垃圾收集器,連線表示垃圾收集器能夠配合使用。算法

  • 單線程與多線程:單線程指的是垃圾收集器只使用一個線程,而多線程使用多個線程;
  • 串行與並行:串行指的是垃圾收集器與用戶程序交替執行,這意味着在執行垃圾收集的時候須要停頓用戶程序;並行指的是垃圾收集器和用戶程序同時執行。除了 CMS 和 G1 以外,其它垃圾收集器都是以串行的方式執行

(1)serial收集器

  serial是新生代下的單線程收集器,它在進行垃圾收集時,必須暫停其餘全部的工做線程,直到它收集結束。它是虛擬機運行在客戶模式下的默認新生代垃圾收集器它的優勢是:簡單高效,在單個 CPU 環境下,因爲沒有線程交互的開銷,所以擁有最高的單線程收集效率服務器

(2)ParNew

  ParNew是serial的多線程版本工做在新生代,是虛擬機在server模式下的首選新生代垃圾收集器除了serial外只有它能和CMS收集器配合工做多線程

​ ParNew在單CPU狀況下,不會取得比serial好的收集效果。併發

(3)paralle scavenge

  paralle scavenge是新生代垃圾收集器,也是使用複製算法的收集器,又是並行的多線程收集器。它關注的點和其餘收集器不一樣,CMS等收集器關注的是儘量的縮短用戶線程停頓時間,而它的目標則是達到一個可控制的吞吐率,所以paralle scavenge收集器也被稱爲「吞吐量優先」收集器。這裏的吞吐量指 CPU 用於運行用戶程序的時間佔總時間的比值性能

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

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

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

(4)serial old

  serial old 是serial的老年代版本,它一樣是單線程的收集器 ,使用標記-整理算法,這個收集器的主要意義也是個client模式下的虛擬機使用 ,若是實在server模式下使用,那它還有兩種用途:對象

  (1)配合paralle scavenge使用。

  (2)做爲CMS的後背預案,在併發收集Concurrent Mode Failure時使用。

(5)Parallel Old

  Parallel Old 時paralle scavenge的老年代版本,使用多線程和標記-整理算法

  在對吞吐量以及CPU資源敏感的場合,優先考慮paralle scavenge和parallel old 收集器。

(6)CMS收集器

  cms收集器是一種獲取最短回收停頓時間爲目標的收集器。cms是基於標記-清除算法實現的。它的運做過程分爲4個部分。

​  (1)初始標記

​  (2)併發標記

​  (3)從新標記

​  (4)併發回收

  初始標記,併發標記這兩步仍然須要「stop the world」(中止用戶線程工做),初始標記僅僅是標記一下GC Roots 能直接關聯到的對象,速度很快併發標記就是進行GC Roots 向下遍歷的過程,速度比較慢,從新標記是爲了修正併發標記期間因用戶程序繼續運做而致使標記產生變更的那一部分對象的標記

  併發標記併發清除這兩部分是耗時最長的,可是這兩階段均可以和用戶線程一塊兒工做,因此從整體上來講,cms收集器的內存回收過程是與用戶線程一塊兒併發執行的

  優勢:併發收集低停頓

  缺點:

  (1)雖然不會致使用戶線程停頓,可是這是以犧牲了總的吞吐量爲代價的,致使cpu利用率不高

  (2)不可以收集浮動垃圾致使full GC產生。因爲cms併發清理階段用戶線程仍在執行,伴隨着程序的運行還會有新的垃圾產生,這部分垃圾出如今標記以後,cms沒法在當次處理他們,只能等到下次GC時在清理。這部分垃圾就稱爲浮動垃圾。

  (3)因爲採用標記-清除算法,產生大量的不連續內存碎片,對大對象的分配帶來麻煩。每每會出現老年代還有很大空間,可是沒法找到連續的空間來分配,不得不提早觸發一次Full GC。

(7)G1收集器

  G1是一款面向服務器應用的垃圾回收器。HotSpot團隊賦予它的使命是代替CMS垃圾收集器,與其餘的GC收集器相比,G1具備如下特色:

  (1)並行與併發:G1能充分利用多cpu的優點,來縮短stop the world停頓時間,部分其餘的GC收集器本來要中止java線程執行GC動做,G1仍然能夠經過併發讓Java線程繼續工做。

  (2)分代收集:分代的概念在G1中仍然保留,可是G1能夠不用和其餘的收集器配合就能獨立的管理整個GC堆,能採用不一樣的方式去處理新建的對象和已經存活了一段時間的對象,熬過屢次GC的舊對象以獲取更好的收集效果。

  (3)空間整合:G1從總體上來看是基於標記-整理算法實現的收集器,從局部上來看(兩個region)是基於複製算法實現的收集器,這兩種算法都意味着G1在收集的過程當中不會產生內存碎片,收集可以提供規整的內存。

  (4)可預測的停頓:G1相對於CMS的優點,G1除了追求低停頓時間外,還可以創建可預測的停頓時間模型,能明確讓使用者指定在一個長度爲M毫秒的時間片斷內,消耗在垃圾收集上的時間不得超過N毫秒。

  G1將整個Java堆分紅多個大小相等的獨立區域(region)雖然還保留老年代和新生代的概念,可是老年代和新生代不是物理隔離的了。

  G1收集器之因此能創建可預測的停頓時間模型,是由於它有計劃的避免在整個java堆進行垃圾回收,G1跟蹤各個region裏面的垃圾堆積的價值大小(回收所得到的空間大小以及回收所需時間的經驗值),在後臺維護一個優先列表,每次根據收集時間,優先回收價值最大的區域,這種使用region劃份內存空間有優先級的回收方式,保證了G1收集器在有限的時間內能夠獲取可能高的收集效率。

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

  若是不維護remembered set,G1的運做分爲如下幾個步驟:

  (1)初始標記

  (2)併發標記

  (3)最終標記

  (4)篩選回收

  初始標記階段僅僅只是標記一下GC Roots能直接關聯到的對象,而且須要修改TAMS的值,讓下一階段用戶程序併發運行時,能在正確可用的region中建立對象,這個階段須要停頓線程,可是停頓時間很短。

  併發標記是從GC Roots開始從堆中對象進行可達性分析,找出存活的對象,這階段耗時較長,可是能夠與用戶線程併發運行。

  最終標記則是爲了修正在併發標記期間因用戶程序繼續運行而致使標記產生變更的那一部分標記記錄,虛擬機將這段時間對象變化記錄在線程remembered set 中,這段須要停頓線程,可是能夠並行進行。

  篩選回收階段首先對各個region的回收價值和成本進行排序,根據用戶所指望的GC時間來指定回收計劃。

相關文章
相關標籤/搜索