Java垃圾回收器

說(shuō)到如何進(jìn)行Jvm虛擬機(jī)優(yōu)化划鸽,第一時(shí)間想到應(yīng)該都是配置堆內(nèi)存的大小,其次就是Java垃圾收集器了。Java垃圾收集器的配置對(duì)于Jvm優(yōu)化來(lái)說(shuō)是一個(gè)很重要的選擇我衬,選擇合適的垃圾收集器可以讓Jvm的性能有一個(gè)很大的提升曹动。截止Jdk 1.8斋日,一共有7款不同的垃圾收集器。每一款不同的垃圾收集器都有不同的特點(diǎn)墓陈,在具體使用的時(shí)候恶守,需要根據(jù)具體的情況選用不同的垃圾收集器。這幾款垃圾收集器之間有如下聯(lián)系:

image

下面一一介紹這些垃圾回收器的特點(diǎn)。

Serial收集器

Serial收集器是一個(gè)基本的,古老的新生代垃圾收集器骂维。這個(gè)垃圾收集器是一個(gè)單線(xiàn)程的收集器廓推,在它進(jìn)行垃圾回收的時(shí)候,其他的工作線(xiàn)程都會(huì)被暫停,直到它收集結(jié)束。這也就是說(shuō),如果Jvm參數(shù)配置有問(wèn)題或者內(nèi)存不夠科侈,導(dǎo)致頻繁的gc,可能每隔一段時(shí)間應(yīng)用就會(huì)暫停響應(yīng)炒事。如果暫停的時(shí)間太長(zhǎng)臀栈,用戶(hù)就無(wú)法接受了,而且這個(gè)過(guò)程是不可控制的挠乳,是虛擬機(jī)在后臺(tái)自動(dòng)發(fā)起和自動(dòng)完成的挂脑。整個(gè)運(yùn)行過(guò)程如下所示:

image

盡管Serial收集器有如此多的缺點(diǎn),但是從JDK1.3開(kāi)始到JDK1.7都一直是默認(rèn)的運(yùn)行在Client模式下的新生代收集器欲侮。原因在于Serial收集器是一個(gè)簡(jiǎn)單高效的收集器崭闲,沒(méi)有線(xiàn)程切換的開(kāi)銷(xiāo)等等,在一般的Client應(yīng)用中需要回收的內(nèi)存也不是很大威蕉,垃圾回收停頓的時(shí)間不是很長(zhǎng)刁俭,是可以接受的。所以韧涨,Serial收集器對(duì)于運(yùn)行在Client模式下的虛擬機(jī)來(lái)說(shuō)是一個(gè)很好的選擇牍戚。

ParNew收集器

ParNew收集器是Serial收集器的多線(xiàn)程版本,除了使用多線(xiàn)程進(jìn)行垃圾收集之外虑粥,其余行為包括Serial收集器可用的所有控制參數(shù)如孝、收集算法、Stop The World娩贷、對(duì)象分配規(guī)則第晰、回收策略等都與Serial收集器完全一樣,它的工作過(guò)程如下:

image

ParNew收集器除了多線(xiàn)程收集之外,其他與Serial收集器相比并沒(méi)有太多創(chuàng)新之處茁瘦,但他卻是許多運(yùn)行在Server模式下的虛擬機(jī)中首選的新生代收集器品抽,其中有一個(gè)與性能無(wú)關(guān)但很重要的原因是,除了Serial收集器外甜熔,目前只有它能與CMS收集器配合工作圆恤。

雖然ParNew收集器是多線(xiàn)程收集,但是它的性能并不一定比Serial收集器好腔稀。因?yàn)榫€(xiàn)程切換等開(kāi)銷(xiāo)的因素盆昙,在單CPU環(huán)境中它的性能是不如Serial收集器的,就算有2個(gè)CPU也不一定能說(shuō)絕對(duì)比Serial好焊虏。但是隨著CPU核數(shù)的增多弱左,其最終效果肯定是優(yōu)于Serial收集器的。

ParNew收集器默認(rèn)會(huì)開(kāi)啟與CPU相同數(shù)量的線(xiàn)程來(lái)進(jìn)行垃圾收集炕淮,可以通過(guò)-XX:ParallelGCThreads參數(shù)來(lái)限制垃圾收集的線(xiàn)程數(shù)。

Parallel Scavenge收集器

Parallel Scavenge收集器是一個(gè)新生代收集器跳夭,它也是使用復(fù)制算法的收集器涂圆,也是并行的多線(xiàn)程收集器”姨荆看上去與ParNew收集器類(lèi)似润歉,實(shí)際上它們的關(guān)注點(diǎn)并不一樣。

ParNew收集器主要關(guān)注的是回收內(nèi)存的速度颈抚,盡可能地縮短垃圾收集時(shí)用戶(hù)線(xiàn)程的停頓時(shí)間踩衩,而Parallel Scavenge收集器的目標(biāo)則是達(dá)到一個(gè)可控制的吞吐量。

停頓時(shí)間越短越適合需要與用戶(hù)交互的程序贩汉,而高吞吐量可以高效率地利用CPU時(shí)間驱富,盡快完成程序的任務(wù),主要適合在后臺(tái)運(yùn)輸而不需要太多交互的任務(wù)匹舞。

Parallel Scavenge收集器提供了兩個(gè)參數(shù)用于精確控制吞吐量褐鸥,分別是控制最大垃圾收集停頓時(shí)間的-XX:MaxGCPauseMillis參數(shù)以及直接設(shè)置吞吐量大小的-XX:GCTimeRatio參數(shù)。如果對(duì)Parallel Scavenge收集器不太熟悉赐稽,可以設(shè)置-XX:+UseAdaptiveSizePolicy叫榕,這個(gè)參數(shù)是一個(gè)開(kāi)關(guān)。打開(kāi)之后不需要手工指定新生代的大墟⒍妗(-Xmn)晰绎、Eden與Survivor區(qū)的比例(-XX:SuvivorRatio)、晉升老年代對(duì)象大欣ǘ (-XX:PretenureSizeThreshold)等細(xì)節(jié)參數(shù)了荞下,虛擬機(jī)會(huì)根據(jù)當(dāng)前系統(tǒng)的運(yùn)行情況收集性能監(jiān)控信息,動(dòng)態(tài)調(diào)整這些參數(shù)以提供最合適的停頓時(shí)間或者最大的吞吐量。

Parallel Scavenge收集器的工作過(guò)程如圖所示:

image

Serial Old收集器

Serial Old是Serial收集器的老年代版本锄弱,它同樣是一個(gè)單線(xiàn)程收集器考蕾,使用“標(biāo)記-整理”算法。這個(gè)收集器的主要意義也是在于給Client模式下的虛擬機(jī)使用会宪。如果在Server模式下肖卧,那么它主要還有兩個(gè)用途:一種用途是在JDK1.5以及之前的版本中與Parallel Scavenge收集器搭配使用,另一種用途就是作為CMS收集器的后備預(yù)案掸鹅,在并發(fā)收集發(fā)生Concurrent Mode Failure時(shí)使用塞帐。Serial Old收集器的工作過(guò)程如圖所示:

image

Parallel Old收集器

Parallel Old收集器是Parallel Scavenge收集器的老年代版本,使用多線(xiàn)程和“標(biāo)記-整理”算法巍沙。這個(gè)收集器是在JDK1.6中才開(kāi)始提供的葵姥,在此之前,新生代的Parallel Scavenge收集器一直處于比較尷尬的狀態(tài)句携。原因是榔幸,如果新生代選擇Parallel Scavenge收集器,老年代除了Serial Old收集器外別無(wú)選擇矮嫉。直到Parallel Old收集器出現(xiàn)后削咆,“吞吐量?jī)?yōu)先”收集器終于有了比較名副其實(shí)的應(yīng)用組合,在注重吞吐量以及CPU資源敏感的場(chǎng)合蠢笋,都可以?xún)?yōu)先考慮Parallel Scavenge加Parallel Old收集器拨齐。Parallel Old收集器的工作過(guò)程如圖所示:

image

CMS收集器

CMS收集器是一種以獲取最短回收停頓時(shí)間為目標(biāo)的收集器。是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的昨寞,它的運(yùn)作過(guò)程相對(duì)于前面幾種收集器來(lái)說(shuō)更復(fù)雜一些瞻惋,分為4個(gè)步驟:

  • 初始標(biāo)記
  • 并發(fā)標(biāo)記
  • 重新標(biāo)記
  • 并發(fā)清除

其中初始標(biāo)記和重新標(biāo)記這兩個(gè)步驟仍然需要“Stop the world”。初始標(biāo)記僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象援岩,速度很快歼狼,并發(fā)標(biāo)記階段就是GC Roots Tracing的過(guò)程,而重新標(biāo)記階段則是為了修正并發(fā)標(biāo)記期間因用戶(hù)程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分對(duì)象的標(biāo)記記錄享怀,這個(gè)階段的停頓時(shí)間一般會(huì)比初始標(biāo)記階段稍長(zhǎng)一些蹂匹,但遠(yuǎn)比并發(fā)標(biāo)記的時(shí)間短。

由于整個(gè)過(guò)程中耗時(shí)最長(zhǎng)的并發(fā)標(biāo)記和并發(fā)清除過(guò)程收集器線(xiàn)程都可以與用戶(hù)線(xiàn)程一起工作凹蜈,所以限寞,從總體上來(lái)說(shuō),CMS收集器的內(nèi)存回收過(guò)程是用戶(hù)線(xiàn)程一起并發(fā)執(zhí)行的仰坦。CMS收集器的工作過(guò)程如圖所示:

image

CMS是一款優(yōu)秀的收集器履植,它的優(yōu)點(diǎn)有:并發(fā)收集、低停頓悄晃,但它有以下3個(gè)明顯的缺點(diǎn):

  • CMS收集器對(duì)CPU資源非常敏感玫霎。在并發(fā)階段凿滤,它雖然不會(huì)導(dǎo)致用戶(hù)停頓,但是會(huì)因?yàn)檎加昧艘徊糠志€(xiàn)程而導(dǎo)致應(yīng)用程序變慢庶近,總吞吐量會(huì)降低翁脆。
  • CMS收集器無(wú)法處理浮動(dòng)垃圾,可能出現(xiàn)“Concurrent Mode Failure”失敗而導(dǎo)致另一次Full GC的產(chǎn)生鼻种。由于CMS并發(fā)清理階段用戶(hù)線(xiàn)程還在運(yùn)行著反番,伴隨著程序運(yùn)行自然就還會(huì)有新的垃圾不斷產(chǎn)生,這部分垃圾出現(xiàn)在標(biāo)記過(guò)程之后叉钥,CMS無(wú)法在檔次收集中處理掉它們罢缸,只好留待下一次GC時(shí)再清理掉。這一部分垃圾就稱(chēng)為“浮動(dòng)垃圾”投队。
  • 最后一個(gè)缺點(diǎn)是枫疆,CMS是基于“標(biāo)記-清除”算法實(shí)現(xiàn)的收集器,容易產(chǎn)生大量的空間碎片敷鸦,導(dǎo)致沒(méi)有足夠大的連續(xù)空間來(lái)分配當(dāng)前對(duì)象息楔,不得不提前觸發(fā)一次Full GC。

G1 收集器

G1收集器是當(dāng)今收集器技術(shù)發(fā)展的最前沿成果之一扒披,是一款面向服務(wù)端應(yīng)用的垃圾收集器值依,它有如下特點(diǎn):

  • 并行與并發(fā):G1能充分利用多CPU,多核環(huán)境下的硬件優(yōu)勢(shì)谎碍,使用多個(gè)CPU來(lái)縮短Stop-The-World停頓的時(shí)間,部分其他收集器原來(lái)需要停頓Java線(xiàn)程執(zhí)行的GC動(dòng)作洞焙,G1收集器仍然可以通過(guò)并發(fā)的方式讓Java程序繼續(xù)執(zhí)行蟆淀。
  • 分代收集:與其他收集器一樣,分代概念在G1中依然得以保留澡匪。雖然G1可以不需要其他收集器配合就能獨(dú)立管理整個(gè)GC堆熔任,但它能夠采用不同的方式去處理新創(chuàng)建的對(duì)象和已經(jīng)存活了一段時(shí)間、熬過(guò)多次GC的舊對(duì)象以獲取更好的收集效果唁情。
  • 空間整合:與CMS的“標(biāo)記——清理”算法不同疑苔,G1從整體來(lái)看是基于“標(biāo)記——整理”算法實(shí)現(xiàn)的收集器,從局部上來(lái)看是基于“復(fù)制”算法實(shí)現(xiàn)的甸鸟,但無(wú)論如何惦费,這兩種算法都意味著G1運(yùn)作期間不會(huì)產(chǎn)生內(nèi)存空間碎片,收集后能提供規(guī)整的可用內(nèi)存抢韭。
  • 可預(yù)測(cè)的停頓:這是G1相對(duì)于CMS的另一大優(yōu)勢(shì)薪贫,降低停頓時(shí)間是G1和CMS共同的關(guān)注點(diǎn),但G1除了追求低停頓外刻恭,還能建立可預(yù)測(cè)的停頓時(shí)間模型瞧省,能讓使用者明確指定在一個(gè)長(zhǎng)度為M毫秒的時(shí)間片段內(nèi),消耗在垃圾收集上的時(shí)間不得超過(guò)N毫秒。

G1收集器的運(yùn)作大致可劃分為以下幾個(gè)步驟:

  • 初始標(biāo)記
  • 并發(fā)標(biāo)記
  • 最終標(biāo)記
  • 篩選標(biāo)記

初始標(biāo)記階段僅僅只是標(biāo)記一下GC Roots能直接關(guān)聯(lián)到的對(duì)象鞍匾,并且修改TAMS(Next Top at Mart Start)的值交洗,讓下一階段用戶(hù)程序并發(fā)運(yùn)行時(shí),能在正確可用的Region中創(chuàng)建新對(duì)象橡淑,這階段需要停頓線(xiàn)程构拳,但耗時(shí)很短。

并發(fā)標(biāo)記階段是從GC Root開(kāi)始對(duì)堆中對(duì)象進(jìn)行可達(dá)性分析梳码,找出存活的對(duì)象隐圾,這階段耗時(shí)較長(zhǎng),但可與用戶(hù)程序并發(fā)執(zhí)行掰茶。

最終標(biāo)記階段則是為了修正在并發(fā)標(biāo)記期間因用戶(hù)程序繼續(xù)運(yùn)作而導(dǎo)致標(biāo)記產(chǎn)生變動(dòng)的那一部分暇藏,這個(gè)階段需要停頓線(xiàn)程,但是可并行執(zhí)行濒蒋。

在篩選回收階段首先對(duì)各個(gè)Region的回收價(jià)值和成本進(jìn)行排序盐碱,根據(jù)用戶(hù)所期望的GC停頓時(shí)間來(lái)制定回收計(jì)劃。

G1收集器的工作過(guò)程如圖所示:

image
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末沪伙,一起剝皮案震驚了整個(gè)濱河市瓮顽,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌围橡,老刑警劉巖暖混,帶你破解...
    沈念sama閱讀 211,194評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場(chǎng)離奇詭異翁授,居然都是意外死亡拣播,警方通過(guò)查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,058評(píng)論 2 385
  • 文/潘曉璐 我一進(jìn)店門(mén)收擦,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)贮配,“玉大人,你說(shuō)我怎么就攤上這事塞赂±崂眨” “怎么了?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,780評(píng)論 0 346
  • 文/不壞的土叔 我叫張陵宴猾,是天一觀(guān)的道長(zhǎng)圆存。 經(jīng)常有香客問(wèn)我,道長(zhǎng)仇哆,這世上最難降的妖魔是什么辽剧? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,388評(píng)論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮税产,結(jié)果婚禮上怕轿,老公的妹妹穿的比我還像新娘偷崩。我一直安慰自己,他們只是感情好撞羽,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,430評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布阐斜。 她就那樣靜靜地躺著,像睡著了一般诀紊。 火紅的嫁衣襯著肌膚如雪谒出。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,764評(píng)論 1 290
  • 那天邻奠,我揣著相機(jī)與錄音笤喳,去河邊找鬼。 笑死碌宴,一個(gè)胖子當(dāng)著我的面吹牛杀狡,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播贰镣,決...
    沈念sama閱讀 38,907評(píng)論 3 406
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼呜象,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了碑隆?” 一聲冷哼從身側(cè)響起恭陡,我...
    開(kāi)封第一講書(shū)人閱讀 37,679評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎上煤,沒(méi)想到半個(gè)月后休玩,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,122評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡劫狠,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,459評(píng)論 2 325
  • 正文 我和宋清朗相戀三年拴疤,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片嘉熊。...
    茶點(diǎn)故事閱讀 38,605評(píng)論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡遥赚,死狀恐怖扬舒,靈堂內(nèi)的尸體忽然破棺而出阐肤,到底是詐尸還是另有隱情,我是刑警寧澤讲坎,帶...
    沈念sama閱讀 34,270評(píng)論 4 329
  • 正文 年R本政府宣布孕惜,位于F島的核電站,受9級(jí)特大地震影響晨炕,放射性物質(zhì)發(fā)生泄漏衫画。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,867評(píng)論 3 312
  • 文/蒙蒙 一瓮栗、第九天 我趴在偏房一處隱蔽的房頂上張望削罩。 院中可真熱鬧瞄勾,春花似錦、人聲如沸弥激。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,734評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)微服。三九已至趾疚,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間以蕴,已是汗流浹背糙麦。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,961評(píng)論 1 265
  • 我被黑心中介騙來(lái)泰國(guó)打工, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留丛肮,地道東北人赡磅。 一個(gè)月前我還...
    沈念sama閱讀 46,297評(píng)論 2 360
  • 正文 我出身青樓,卻偏偏與公主長(zhǎng)得像腾供,于是被迫代替她去往敵國(guó)和親仆邓。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,472評(píng)論 2 348

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