收集算法是內存回收的方法論,垃圾收集器就是內存回收的具體實現。收集器主要分三類:串行收集器、並行收集器以及併發收集器。java
一、併發和並行算法
a:並行(Parallel):指多條垃圾收集線程並行工做,但此時用戶線程仍然處於等待狀態。多線程
b:併發(Concurrent):指用戶線程與垃圾收集線程同時執行(但不必定是並行的,可能會交替執行),用戶程序在繼續運行,而垃圾收集程序運行在另外一個CPU上。併發
二、新生代 GC 和老年代GC性能
a:新生代GC(Minor GC):指發生在新生代的垃圾收集動做,由於Java對象大多都具有朝生夕滅的特性,因此Minor GC很是頻繁,通常回收速度也比較快。網站
b:老年代GC(Major GC / Full GC):指發生在老年代的GC,出現了Major GC,常常會伴隨至少一次的Minor GC(但非絕對的)。Major GC的速度通常會比Minor GC慢10倍以上。spa
三、吞吐量線程
吞吐量就是CPU用於運行用戶代碼的時間與CPU總消耗時間的比值,即吞吐量 = 運行用戶代碼時間 /(運行用戶代碼時間 + 垃圾收集時間)。3d
虛擬機總共運行了100分鐘,其中垃圾收集花掉1分鐘,那吞吐量就是99%。對象
串行收集器是最古老,最穩定以及效率高的收集器,可能會產生較長的停頓,只使用一個線程去回收。
新生代、老年代使用串行回收;新生代複製算法、老年代標記-壓縮;垃圾收集的過程當中會Stop The World(服務暫停)
參數控制:-XX:+UseSerialGC 串行收集器
ParNew收集器其實就是Serial收集器的多線程版本。新生代並行,老年代串行;新生代複製算法、老年代標記-壓縮
參數控制:-XX:+UseParNewGC ParNew收集器
-XX:ParallelGCThreads 限制線程數量
Serial收集器 VS ParNew收集器
ParNew收集器在單CPU的環境中絕對不會有比Serial收集器更好的效果,甚至因爲存在線程交互的開銷,該收集器在經過超線程技術實現的兩個CPU的環境中都不能百分之百地保證能夠超越Serial收集器。
然而,隨着可使用的CPU的數量的增長,它對於GC時系統資源的有效利用仍是頗有好處的。
是一個新生代收集器,他也是使用複製算法的收集器,又是並行的多線程收集器。Parallel收集器更關注系統的吞吐量。
也能夠經過參數控制GC的時間不大於多少毫秒或者比例;新生代複製算法、老年代標記-壓縮
參數控制:-XX:+UseParallelGC 使用Parallel收集器+ 老年代串行
Parallel Scavenge收集器 VS CMS等收集器
CMS等收集器的關注點是儘量地縮短垃圾收集時用戶線程的停頓時間,而Parallel Scavenge收集器的目標則是達到一個可控制的吞吐量(Throughput)。
因爲與吞吐量關係密切,Parallel Scavenge收集器也常常稱爲「吞吐量優先」收集器。
Parallel Scavenge收集器 VS ParNew收集器
Parallel Scavenge收集器與ParNew收集器的一個重要區別是它具備自適應調節策略。
GC自適應的調節策略
Parallel Scavenge收集器有一個參數-XX:+UseAdaptiveSizePolicy。當這個參數打開以後,就不須要手工指定新生代的大小。
Eden與Survivor區的比例、晉升老年代對象年齡等細節參數了,虛擬機會根據當前系統的運行狀況收集性能監控信息,動態調整這些參數以提供最合適的停頓時間或者最大的吞吐量,這種調節方式稱爲GC自適應的調
節策略(GC Ergonomics)。
它是Serial收集器的老年代版,它一樣是一個單線程收集器,使用「標記--整理」算法。
是Parallel Scavenge收集器的老年代版,使用多線程與「標記--整理」算法。
是一種以獲取最短回收停頓時間爲目標的收集器。目前很大一部分的java應用集中在互聯網站或者B/S系統的服務端上,這類應用尤爲重視服務的響應速度,但願系統停頓時間最短,以給用戶帶來較好的體驗。
CMS收集器就很是符合這類應用的需求。
CMS收集器是基於「標記--清除」算法實現的, 他的運做過程相對於前幾種收集器來講更復雜一些,整個過程分爲4個步驟:
a、初始標記(CMS inital mark):須要「stop the world」,但只標記一下GC Roots能直接關聯的對象,速度很快。
b、併發標記(CMS concurrent mark):是GC Roots Tracing的過程,花費時間長
c、從新標記(CMS remark):是爲了修正併發標記期間因用戶程序繼續運行而致使標記產生變更的那一部分對象的標記記錄,這個階段時間通常會比初始標記階段稍長一些,但遠比並發標記的時間短。
d、併發清除(CMS concurrent sweep):是併發清除無用對象。
(
因爲整個過程當中耗時最長的併發標記和併發清除過程收集器線程均可以與用戶線程一塊兒工做,因此,從整體上來講,CMS收集器的內存回收過程是與用戶線程一塊兒併發執行的。
優勢
CMS是一款優秀的收集器,它的主要優勢在名字上已經體現出來了:併發收集、低停頓。
缺點
(1)CMS收集器對CPU資源很是敏感
在併發階段,它雖然不會致使用戶線程停頓,可是會由於佔用了一部分線程(或者說CPU資源)而致使應用程序變慢,總吞吐量會下降。
(2)CMS收集器沒法處理浮動垃圾
因爲CMS併發清理階段用戶線程還在運行着,伴隨程序運行天然就還會有新的垃圾不斷產生,這一部分垃圾出如今標記過程以後,CMS沒法在當次收集中處理掉它們,只好留待下一次GC時再清理掉。這一部分垃
圾就稱爲「浮動垃圾」。
(3)CMS收集器會產生大量空間碎片
CMS是一款基於「標記—清除」算法實現的收集器,這意味着收集結束時會有大量空間碎片產生。
空間碎片過多時,將會給大對象分配帶來很大麻煩,每每會出現老年代還有很大空間剩餘,可是沒法找到足夠大的連續空間來分配當前對象,不得不提早觸發一次Full GC。
G1(Garbage-First)是一款面向服務端應用的垃圾收集器。
與CMS收集器相比有如下優勢:
(1)沒有大量空間碎片
與CMS的「標記—清理」算法不一樣,G1從總體來看是基於「標記—整理」算法實現的收集器,從局部(兩個Region之間)上來看是基於「複製」算法實現的。
(2)可預測的停頓
這是G1相對於CMS的另外一大優點,下降停頓時間是G1和CMS共同的關注點,但G1除了追求低停頓外,還能創建可預測的停頓時間模型,能讓使用者明確指定在一個長度爲M毫秒的時間片斷內,消耗在垃圾收集上的
時間不得超過N毫秒。
G1收集器執行過程
a、初始標記(Initial Marking)
初始標記階段僅僅只是標記一下GC Roots能直接關聯到的對象,而且修改TAMS的值,讓下一階段用戶程序併發運行時,能在正確可用的Region中建立新對象,這階段須要停頓線程,但耗時很短。
b、併發標記(Concurrent Marking)
併發標記階段是從GC Root開始對堆中對象進行可達性分析,找出存活的對象,這階段耗時較長,但可與用戶程序併發執行。
c、最終標記(Final Marking)
最終標記階段是爲了修正在併發標記期間因用戶程序繼續運做而致使標記產生變更的那一部分標記記錄,虛擬機將這段時間對象變化記錄在線程Remembered Set Logs裏面,最終標記階段須要把Remembered Set
Logs的數據合併到Remembered Set中,這階段須要停頓線程,可是可並行執行。
d、篩選回收(Live Data Counting and Evacuation)
篩選回收階段首先對各個Region的回收價值和成本進行排序,根據用戶所指望的GC停頓時間來制定回收計劃,這個階段其實也能夠作到與用戶程序一塊兒併發執行,可是由於只回收一部分Region,時間是用戶可控制
的,並且停頓用戶線程將大幅提升收集效率。
雖然咱們是在對各個收集器進行比較,但並不是爲了挑選出一個最好的收集器。由於直到如今爲止尚未最好的收集器出現,更加沒有萬能的收集器,因此咱們選擇的只是對具體應用最合適的收集器。
經常使用的收集器組合
新生代GC策略 | 年老代GC策略 | 說明 | |
組合1 | Serial | Serial Old |
Serial和Serial Old都是單線程進行GC,特色就是GC時暫停全部應用線程。
|
組合2 | Serial | CMS+Serial Old | CMS(Concurrent Mark Sweep)是併發GC,實現GC線程和應用線程併發工做,不須要暫停全部應用線程。另外,當CMS進行GC失敗時,會自動使用Serial Old策略進行GC。 |
組合3 |
ParNew
|
CMS |
使用-XX:+UseParNewGC選項來開啓。ParNew是Serial的並行版本,能夠指定GC線程數,默認GC線程數爲CPU的數量。可使用-XX:ParallelGCThreads選項指定GC的線程數。
若是指定了選項-XX:+UseConcMarkSweepGC選項,則新生代默認使用ParNew GC策略。
|
組合4 |
ParNew
|
Serial Old | 使用-XX:+UseParNewGC選項來開啓。新生代使用ParNew GC策略,年老代默認使用Serial Old GC策略。 |
組合5 |
Parallel Scavenge
|
Serial Old |
Parallel Scavenge策略主要是關注一個可控的吞吐量:應用程序運行時間 / (應用程序運行時間 + GC時間),可見這會使得CPU的利用率儘量的高,適用於後臺持久運行的應用程序,而不適用於交互較多的應用程序。
|
組合6 |
Parallel Scavenge
|
Parallel Old |
Parallel Old是Serial Old的並行版本
|
組合7 |
G1GC
|
G1GC |
-XX:+UnlockExperimentalVMOptions -XX:+UseG1GC #開啓
-XX:MaxGCPauseMillis =50 #暫停時間目標 -XX:GCPauseIntervalMillis =200 #暫停間隔目標 -XX:+G1YoungGenSize=512m #年輕代大小 -XX:SurvivorRatio=6 #倖存區比例 |
圖形展現
圖中展現了7種做用於不一樣分代的收集器,若是兩個收集器之間存在連線,就說明它們能夠搭配使用。虛擬機所處的區域,則表示它是屬於新生代收集器仍是老年代收集器。
想太多,作太少,中間的落差就是煩惱。想沒有煩惱,要麼別想,要麼多作。少校【17】