垃圾收集器與內(nèi)存分配策略(三)——七種垃圾收集器

如果說收集算法是內(nèi)存回收的方法論砍濒,那么垃圾收集器就是內(nèi)存回收的具體實現(xiàn)茧彤。Java虛擬機規(guī)范中對垃圾收集器應該如何實現(xiàn)并沒有任何規(guī)定狮鸭,因此不同廠商饰剥、不同版本的虛擬機所提供的垃圾收集器可能會有很大差別。這里討論的收集器基于JDK 1.7 Update 14之后的HotSpot虛擬機(在這個版本中正式提供了商用的G1收集器蒋歌,之前G1仍然處于試驗狀態(tài)帅掘,JDK11已經(jīng)作為默認的收集器),這個虛擬機所包含的所有收集器如下圖:


Se

一堂油、Serial收集器(新生代)

最原生的收集器, jdk1.3以前唯一的選擇.
單線程收集器. 這里并不是指使用一個CPU或一條收集線程去完成垃圾收集工作, 而是指它在收集垃圾時, 必須暫停用戶工作線程(Stop The World).


image.png
  • 單線程
    只會使用一個CPU或一條GC線程進行GC,并且在GC過程中暫停其他所有的工作線程,因此用戶的請求或圖形化界面會出現(xiàn)卡頓

  • 適合Client模式
    一般客戶端應用所需內(nèi)存較小,不會創(chuàng)建太多的對象,而且堆內(nèi)存不大,因此GC時間比較短,即使在這段時間停止一切用戶線程,也不會感到明顯停頓

  • 簡單高效
    由于Serial收集器只有一條GC線程,避免了線程切換的開銷

  • 采用"復制"算法

二修档、ParNew收集器(新生代)

ParNew是Serial的多線程版本


image.png
  • 多線程并行執(zhí)行
    ParNew由多條GC線程并行地進行垃圾清理.
    但清理過程仍然需要暫停一切其他用戶線程.
    但由于有多條GC線程同時清理,清理速度比Serial有一定的提升
  • 適合多CPU服務器的環(huán)境
    由于使用多線程,是許多運行在 server 模式下的虛擬機首選的新生代收集器
    與Serial性能對比ParNew和Serial唯一區(qū)別就是使用了多線程垃圾回收,在多CPU的環(huán)境下性能比Serial會有一定程度的提升。但線程切換需要額外的開銷,因此在單CPU環(huán)境中表現(xiàn)不如Serial,雙CPU環(huán)境也不一定就比Serial高效府框。默認開啟的收集線程數(shù)與CPU數(shù)量相同吱窝。
  • 采用"復制"算法
  • 追求“降低停頓時間”
    和Serial相比,ParNew使用多線程的目的就是縮短GC時間,從而減少用戶線程被停頓的時間。
  • 使用參數(shù)
    使用參數(shù) -XX:+UseParNewGC
    限制線程數(shù) -XX:ParallelGCThreads

三迫靖、Parallel Scavenge收集器(新生代)

吞吐量優(yōu)先收集器院峡,Parallel Scavenge和ParNew一樣都是并行的多線程、新生代收集器,都使用"復制"算法(Stop-The-World)進行垃圾回收系宜。
ParNew收集器追求降低GC時用戶線程的停頓時間,適合交互式應用,良好的反應速度提升用戶體驗照激。
Parallel Scavenge追求可控的CPU吞吐量,能夠在較短的時間內(nèi)完成指定任務,適合不需太多交互的后臺運算。


image.png
  • 優(yōu)點:可以精確控制吞吐量
  • 缺點:原本10s收集一次, 每次停頓100ms, 設置完參數(shù)之后可能變成5s收集一次, 每次停頓70ms. 停頓時間變短, 但收集次數(shù)變多

四盹牧、Serial Old收集器(老年代)

Serial的老年代版本,都是單線程收集器,GC時只啟動一條GC線程,因此都適合客戶端應用.
它們唯一的區(qū)別就是:Serial Old工作在老年代,使用"標記-整理"算法俩垃;Serial工作在新生代,使用"復制"算法。

五汰寓、Parallel Old收集器(老年代)

Parallel Scavenge收集器的老年代版本口柳。
在jdk1.6之前, 如果新生代選擇了Parallel Scaenge收集器, 老年代除了Serial Old(PS Mark Sweep)收集器外別無選擇.( 上面說過, Parallel Scavenge收集器無法與CMS-Concurrent Mark Sweep收集器搭配工作)。但是現(xiàn)在可以使用Parallel Scavenge + Parallel Old組合. 而不必像之前那樣Prallel Scavenge + Serial Old組合.

六有滑、CMS收集器(老年代)

(Concurrent Mark Sweep Collector) : 低延遲為先!
回收停頓時間比較短跃闹、目前比較常用的垃圾回收器。它通過初始標記(InitialMark)俺孙、并發(fā)標記(Concurrent Mark)、重新標記( Remark)掷贾、并發(fā)清除( Concurrent Sweep )四個步驟完成垃圾回收工作睛榄。


image.png

有兩步需要"Stop The World":初始標記和重新標記。

  • 初始標記 (Initial Mark)
    停止一切用戶線程,僅使用一條初始標記線程對所有與GC Roots直接相關聯(lián)的 老年代對象進行標記,速度很快
  • 并發(fā)標記 (Concurrent Marking Phase)
    使用多條并發(fā)標記線程并行執(zhí)行,并與用戶線程并發(fā)執(zhí)行.此過程進行可達性分析,標記所有這些對象可達的存貨對象,速度很慢
  • 重新標記 ( Remark)
    因為并發(fā)標記時有用戶線程在執(zhí)行想帅,標記結果可能有變化
    停止一切用戶線程,并使用多條重新標記線程并行執(zhí)行,重新遍歷所有在并發(fā)標記期間有變化的對象進行最后的標記.這個過程的運行時間介于初始標記和并發(fā)標記之間
  • 并發(fā)清除 (Concurrent Sweeping)
    只使用一條并發(fā)清除線程,和用戶線程們并發(fā)執(zhí)行,清除剛才標記的對象
    這個過程非常耗時

CMS的缺點:

  • 吞吐量低
    由于CMS在GC過程用戶線程和GC線程并行,從而有線程切換的額外開銷
    因此CPU吞吐量就不如在GC過程中停止一切用戶線程的方式來的高
  • 無法處理浮動垃圾,導致頻繁Full GC
    由于垃圾清除過程中,用戶線程和GC線程并發(fā)執(zhí)行,也就是用戶線程仍在執(zhí)行,那么在執(zhí)行過程中會產(chǎn)生垃圾,這些垃圾稱為"浮動垃圾"
    如果CMS在GC過程中,用戶線程需要在老年代中分配內(nèi)存時發(fā)現(xiàn)空間不足,就需再次發(fā)起Full GC,而此時CMS正在進行清除工作,因此此時只能由Serial Old臨時對老年代進行一次Full GC
  • 使用"標記-清除"算法產(chǎn)生碎片空間
    由于CMS使用了"標記-清除"算法, 因此清除之后會產(chǎn)生大量的碎片空間,不利于空間利用率.不過CMS提供了應對策略:
    1场靴、開啟-XX:+UseCMSCompactAtFullCollection
    開啟該參數(shù)后,每次FullGC完成后都會進行一次內(nèi)存壓縮整理,將零散在各處的對象整理到一塊兒.但每次都整理效率不高,因此提供了以下參數(shù).
    2、設置參數(shù)-XX:CMSFullGCsBeforeCompaction
    本參數(shù)告訴CMS,經(jīng)過了N次Full GC過后再進行一次內(nèi)存整理.

CMS應用場景:
目前很大一部分的Java應用集中在互聯(lián)網(wǎng)網(wǎng)站或B/S系統(tǒng)的服務端上,這類應用尤其重視服務的響應速度旨剥,希望系統(tǒng)停時間最短咧欣,以給用戶帶來較好的體驗。CMS收集器非常符合這類應用的需求轨帜。

七魄咕、G1收集器(萬能收集器)

Hotspot 在JDK7中推出了新一代 G1 ( Garbage-First Garbage Collector )垃圾回收,通過

-XX:+UseG1GC

參數(shù)啟用
和CMS相比蚌父,Gl具備壓縮功能哮兰,能避免碎片向題,G1的暫停時間更加可控苟弛。性能總體還是非常不錯的,G1是當今最前沿的垃圾收集器成果之一.


image.png

G1收集器相關概念

  • G1的內(nèi)存模型
    沒有新生代和老年代的概念,而是將Java堆劃分為一塊塊獨立的大小相等的Region.
    當要進行垃圾收集時,首先估計每個Region中的垃圾數(shù)量,每次都從垃圾回收價值最大的Region開始回收,因此可以獲得最大的回收效率
  • Remembered Set
    一個對象和它內(nèi)部所引用的對象可能不在同一個Region中,那么當垃圾回收時,是否需要掃描整個堆內(nèi)存才能完整地進行一次可達性分析?
    當然不是,每個Region都有一個Remembered Set,用于記錄本區(qū)域中所有對象引用的對象所在的區(qū)域,從而在進行可達性分析時,只要在GC Roots中再加上Remembered Set即可防止對所有堆內(nèi)存的遍歷.

G1收集器特點:

  • 并行與并發(fā):G1能充分利用多CPU喝滞,多核環(huán)境下的硬件優(yōu)勢,使用多個CPU來縮短Stop-The-World停頓時間膏秫,部分其他收集器原本需要停頓Java線程執(zhí)行的GC動作右遭,G1收集器仍然可以通過并發(fā)的方式讓Java程序繼續(xù)執(zhí)行。
  • 分代收集:與其他收集器一樣缤削,分代概念在G1中得以保留窘哈。
  • 空間整合:與CMS的“標記-清理”算法不同,G1從整體來看是基于“標記-整理”算法實現(xiàn)的收集器,從局部上來看是基于“復制”算法實現(xiàn)的目派,這兩種算法都不會產(chǎn)生內(nèi)存空間碎片岔留。
  • 可預測的停頓:這是G1相對于CMS的另一大優(yōu)勢,降低停頓時間是G1和CMS共同關注點满哪,但G1除了追求低停頓外,還能建立可預測的停頓時間模型劝篷,能讓使用者明確指定在一個長度為M毫秒的時間片段內(nèi)哨鸭,消耗在垃圾收集器上的時間不得超過N毫秒,這幾乎已經(jīng)是實時Java(RTSJ)的垃圾收集器的特征了娇妓。

G1垃圾收集過程

  • 初始標記
    標記與GC Roots直接關聯(lián)的對象,停止所有用戶線程,只啟動一條初始標記線程,這個過程很快.
  • 并發(fā)標記
    進行全面的可達性分析,開啟一條并發(fā)標記線程與用戶線程并行執(zhí)行.這個過程比較長.
  • 最終標記
    標記出并發(fā)標記過程中用戶線程新產(chǎn)生的垃圾.停止所有用戶線程,并使用多條最終標記線程并行執(zhí)行.
  • 篩選回收
    回收廢棄的對象.此時也需要停止一切用戶線程,并使用多條篩選回收線程并行執(zhí)行.

S0/S1的功能由G1中的Survivor region來承載,通過GC日志可以觀察到完整的垃圾回收過程如下像鸡,其中就有Survivor regions的區(qū)域從0個到1個


image.png

紅色標識的為G1中的四種region,都處于Heap中.
G1執(zhí)行時使用4個worker并發(fā)執(zhí)行,在初始標記時哈恰,還是會觸發(fā)STW,如第一步所示的Pause

最后編輯于
?著作權歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末只估,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子着绷,更是在濱河造成了極大的恐慌蛔钙,老刑警劉巖,帶你破解...
    沈念sama閱讀 212,542評論 6 493
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件荠医,死亡現(xiàn)場離奇詭異吁脱,居然都是意外死亡桑涎,警方通過查閱死者的電腦和手機,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,596評論 3 385
  • 文/潘曉璐 我一進店門兼贡,熙熙樓的掌柜王于貴愁眉苦臉地迎上來攻冷,“玉大人,你說我怎么就攤上這事遍希〉嚷” “怎么了?”我有些...
    開封第一講書人閱讀 158,021評論 0 348
  • 文/不壞的土叔 我叫張陵孵班,是天一觀的道長涉兽。 經(jīng)常有香客問我,道長篙程,這世上最難降的妖魔是什么枷畏? 我笑而不...
    開封第一講書人閱讀 56,682評論 1 284
  • 正文 為了忘掉前任,我火速辦了婚禮虱饿,結果婚禮上拥诡,老公的妹妹穿的比我還像新娘。我一直安慰自己氮发,他們只是感情好渴肉,可當我...
    茶點故事閱讀 65,792評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著爽冕,像睡著了一般仇祭。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上颈畸,一...
    開封第一講書人閱讀 49,985評論 1 291
  • 那天乌奇,我揣著相機與錄音,去河邊找鬼眯娱。 笑死礁苗,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的徙缴。 我是一名探鬼主播试伙,決...
    沈念sama閱讀 39,107評論 3 410
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼于样!你這毒婦竟也來了疏叨?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,845評論 0 268
  • 序言:老撾萬榮一對情侶失蹤穿剖,失蹤者是張志新(化名)和其女友劉穎蚤蔓,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體携御,經(jīng)...
    沈念sama閱讀 44,299評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡昌粤,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,612評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了啄刹。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片涮坐。...
    茶點故事閱讀 38,747評論 1 341
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖誓军,靈堂內(nèi)的尸體忽然破棺而出袱讹,到底是詐尸還是另有隱情,我是刑警寧澤昵时,帶...
    沈念sama閱讀 34,441評論 4 333
  • 正文 年R本政府宣布捷雕,位于F島的核電站,受9級特大地震影響壹甥,放射性物質(zhì)發(fā)生泄漏救巷。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 40,072評論 3 317
  • 文/蒙蒙 一句柠、第九天 我趴在偏房一處隱蔽的房頂上張望浦译。 院中可真熱鬧,春花似錦溯职、人聲如沸精盅。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,828評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽叹俏。三九已至,卻和暖如春僻族,著一層夾襖步出監(jiān)牢的瞬間粘驰,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 32,069評論 1 267
  • 我被黑心中介騙來泰國打工鹰贵, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留晴氨,地道東北人。 一個月前我還...
    沈念sama閱讀 46,545評論 2 362
  • 正文 我出身青樓碉输,卻偏偏與公主長得像籽前,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子敷钾,可洞房花燭夜當晚...
    茶點故事閱讀 43,658評論 2 350

推薦閱讀更多精彩內(nèi)容