沒有最好的垃圾收集器尺借,也沒有萬能的垃圾收集器招狸,只有針對具體應(yīng)用的最合適的垃圾收集器
前言-垃圾收集器的并行與并發(fā)
- 并行(Parallel氯哮,同時執(zhí)行):多個線程同時進(jìn)行垃圾收集续崖,但是所有用戶線程都處于暫停狀態(tài)
- 并發(fā)(Concurrent宪睹,并行發(fā)生):指的是用戶線程和垃圾收集線程同時進(jìn)行,當(dāng)然了此時的垃圾收集線程也可以是單線程的岗照。
1- Serial (串行) 收集器
- 不僅意味著使用一個線程或者CPU進(jìn)行垃圾收集村象。
- 還體現(xiàn)在垃圾收集的串行順序操作上笆环,即只能暫停當(dāng)前所有java線程,執(zhí)行垃圾收集直到垃圾回收的結(jié)束厚者。
使用的收集算法:Copying復(fù)制算法
- 特點(diǎn):1.停頓時間長躁劣。2.簡單高效,沒有線程交互的開銷
- 應(yīng)用場景:Client端新生代垃圾收集
2- Serial Old 收集器
Serial 的老年代版本
收集算法:串行(Mark-Compact)標(biāo)記-整理算法
3- ParNew (Parallel New Generation)收集器
Serial 的多線程的版本库菲,并行的Serial收集器
- 特點(diǎn):1.存在線程交互的開銷账忘,單CPU的情況下效率不高,2. 但是在多CPU的情況下能充分利用系統(tǒng)資源進(jìn)行垃圾收集
- 應(yīng)用場景:Server端首選的新生代垃圾收集器熙宇,因?yàn)樵赟erver端除了Serial外只有它能與CMS配合使用
4- Parallel Scavenge (并行清除)收集器
新生代收集器鳖擒、吞吐量優(yōu)先收集器
- 收集算法:并行的Copying復(fù)制算法
- 無法和CMS收集器配合使用
- 與其他所有收集器不同的地方--關(guān)注的點(diǎn)不同--關(guān)注可控的吞吐量(其他的則為停頓時間)
- 吞吐量 = 運(yùn)行用戶代碼的時間 / (運(yùn)行用戶代碼的時間 + 垃圾收集的時間),衡量的是CPU的利用率
- 其他收集器減少停頓時間是通過犧牲吞吐量來實(shí)現(xiàn)的:減小新生代的分區(qū)大小烫止,來達(dá)到快速回收的目的蒋荚,但是很快新生代空間不足,導(dǎo)致更頻繁的垃圾收集(代價(jià)主要體現(xiàn)在線程的交互上烈拒,因?yàn)?strong>線程暫停到恢復(fù)需要一定的時間)
- 應(yīng)用場景:非交互應(yīng)用--密集計(jì)算型程序(不需要太多交互圆裕,只要盡快的得到結(jié)果)
- GC 自適應(yīng)的調(diào)節(jié)策略:使能這個垃圾收集器時,就不需要指定新生代的大小荆几,晉升老年代對象大小這樣的細(xì)節(jié)吓妆,虛擬機(jī)會根據(jù)當(dāng)前系統(tǒng)的運(yùn)行信息,動態(tài)的調(diào)整這些參數(shù)以達(dá)到最合適的停頓時間或者最大的吞吐量
5- Parallel Old 收集器
Parallel Scavenge收集器的老年代版本
- 收集算法:并行的Mark-Compact算法
- 使用場景:當(dāng)新生代使用 Parallel Scavenge收集器時吨铸,老年代就不能使用CMS收集器了行拢,而使用Series Old收集器在Server端效率太低,所以就出現(xiàn)了 Parallel Old 來搭配使用诞吱,實(shí)現(xiàn)真正的吞吐量優(yōu)先舟奠,適用于注重吞吐量和CPU資源敏感的場合
6- CMS(Concurrent Mark Sweep)收集器
并發(fā)標(biāo)記清除:以最短回收停頓時間為目標(biāo)
- 步驟
- ** 初始標(biāo)記:需要暫停所有用戶線程,不過這個階段只標(biāo)記GC Roots直接關(guān)聯(lián)對象**房维,所以停頓時間較短沼瘫。
- 并發(fā)標(biāo)記:恢復(fù)1中暫停的線程,并發(fā)的對1中標(biāo)記的直接關(guān)聯(lián)對象的輪詢咙俩,以標(biāo)記這些對象可訪問的對象耿戚。
- 重新標(biāo)記:需要暫停整個應(yīng)用,在2中(并發(fā)標(biāo)記期間)應(yīng)用可能會修改對象的引用關(guān)系或創(chuàng)建新的對象阿趁,所以要這部分改變或新創(chuàng)建的對象進(jìn)行掃描膜蛔,重新標(biāo)記。
- 并發(fā)清除:恢復(fù)3中暫停的線程脖阵,進(jìn)行并發(fā)的集中清除標(biāo)記過的對象皂股。
- 明顯的缺點(diǎn)
- CMS對CPU資源非常敏感,在并發(fā)階段命黔,因?yàn)檎加幂^多的CPU資源而導(dǎo)致應(yīng)用程序變慢呜呐,總吞吐量會降低就斤。
- 無法處理浮動垃圾(程序運(yùn)行過程中出現(xiàn)在標(biāo)記之后的只能在下一次GC時再被清理的垃圾),因?yàn)镃MS收集器不會像其他垃圾收集器那樣等到老年代幾乎完全被填滿了在進(jìn)行收集卵史,需要預(yù)留一部分空間提供并發(fā)收集的程序運(yùn)行使用战转。要是CMS運(yùn)行期間預(yù)留的內(nèi)存無法滿足程序的需要搜立,就會觸發(fā)Concurrent Mode Failure以躯。
- CMS是基于“標(biāo)記——清除”的并發(fā)收集器,收集結(jié)束時會出現(xiàn)大量的空間碎片啄踊,用 free list 保存可用空間忧设,但是大量碎片會造成明明老年代有大量可用空間,但是在分配大對象時找不到足夠的連續(xù)空間來存放這個大對象颠通,這將觸發(fā)一次 Full GC 址晕。
- 使用場景:常用于B/S架構(gòu)的服務(wù)端上,這類應(yīng)用尤其重視服務(wù)器的響應(yīng)速度顿锰,希望系統(tǒng)停頓時間最短谨垃,已給用戶帶來較好的體驗(yàn)。
7- G1(Garbage-First) 收集器
面向服務(wù)器端應(yīng)用的垃圾收集器硼控,目標(biāo)使用來替換CMS刘陶,克服CMS的缺點(diǎn)
- 步驟(可與CMS進(jìn)行對比)
- ** 初始標(biāo)記:需要暫停所有用戶線程,不過這個階段只標(biāo)記GC Roots直接關(guān)聯(lián)對象牢撼,并修改TAMS(Next Top at Mark Start)的值**匙隔,所以停頓時間較短。
- 并發(fā)標(biāo)記:恢復(fù)1中暫停的線程熏版,從 GC Root開始對堆中對象進(jìn)行可達(dá)性分析纷责,找出存活對象。
- 最終標(biāo)記(可并行執(zhí)行):需要暫停整個應(yīng)用撼短,在2中(并發(fā)標(biāo)記期間)應(yīng)用可能會修改對象的引用關(guān)系或創(chuàng)建新的對象再膳,所以要這部分改變或新創(chuàng)建的對象的變化記錄在線程 Remembered Set Logs里面,最終標(biāo)記階段需要把 Remembered Set Logs 的數(shù)據(jù)合并到 Remembered Set 中曲横。
- 篩選回收(可并行執(zhí)行):恢復(fù)3中暫停的線程喂柒,首先對各個region的回收價(jià)值和成本進(jìn)行排序,根據(jù)用戶所期望的GC停頓時間來制定回收計(jì)劃胜榔,因?yàn)橹换厥找徊糠諶egion胳喷,時間是由用戶控制的,將大幅提升收集的效率夭织。
- 優(yōu)點(diǎn)
- 并發(fā)與并行:充分利用多CPU吭露、多核環(huán)境下的硬件優(yōu)勢,使用多個CPU來減少停頓線程的時間尊惰,G1可用通過并發(fā)讓用戶線程繼續(xù)執(zhí)行讲竿。
- 分代收集:分代的概念在G1中得到保存泥兰,G1不需要其他垃圾收集器進(jìn)行配合就能對整個堆進(jìn)行回收,而且對于新創(chuàng)建的题禀、已經(jīng)存活很久的鞋诗、多次GC仍存活的對象的收集效果很好,可以說是個全能的家伙迈嘹。
- 空間整合:G1整體上是基于“標(biāo)記——整理”算法實(shí)現(xiàn)的削彬,從局部上(兩個Region之間)是基于“復(fù)制”算法實(shí)現(xiàn)的,所以有這兩種算法保證了G1運(yùn)行期間不會產(chǎn)生空間碎片秀仲,收集后能提供規(guī)整的可用內(nèi)存融痛。
- 可預(yù)測的停頓:相比CMS,G1建立了可預(yù)測的停頓時間模型神僵,能讓使用者明確指定在一定長度為M毫秒的時間片段內(nèi)雁刷,消耗在垃圾收收集上的時間不得超過N毫秒,幾乎逼近了實(shí)時垃圾收集器的性能了保礼∨胬可以有計(jì)劃的避免在整個Java堆上進(jìn)行全區(qū)域的垃圾收集。具體為:G1跟蹤各個Region里面的垃圾堆積的價(jià)值大信谡稀(回收所獲得的的空間大小與需要花費(fèi)時間的經(jīng)驗(yàn)值的綜合考量)目派,并在后臺維護(hù)一個優(yōu)先列表,每次根據(jù)允許的收集時間铝阐,優(yōu)先回收價(jià)值最大的Region(Garbage-First)址貌,這種使用Region劃分內(nèi)存空間以及有優(yōu)先級的區(qū)域回收方式,保證了G1收集器在有限的時間內(nèi)可以獲取盡可能高的收集效率徘键。
- Region
在G1收集器中练对,將Java堆的劃分為多個大小相等的獨(dú)立區(qū)域(Region),雖然還保留新生代和老年代的概念吹害,但是已經(jīng)不是物理上隔離的了螟凭,它們都是一部分Region的集合(不需要連續(xù))