JVM那點事-垃圾收集器(1次10ms的GC和10次1ms的GC忠售,你會選哪個传惠?)

小胖在寫完這篇文章后,問自己的幾個問題稻扬。我想卦方,看完這篇文章,你可能就會有自己的答案了泰佳。

  1. 1次10msGC和10次1ms的GC你會選擇哪種盼砍?
  2. CMS收集器缺陷是什么?
  3. 提高CMS的啟動閾值一定能提高性能嗎?為什么逝她?
  4. G1收集器為什么可以設(shè)置停頓時間浇坐?
  5. GC如何確定對象是否可被回收?
  6. 針對你說的“可達性分析法”黔宛,Minor GC時會掃描整個堆嗎近刘?
  7. JDK8默認的垃圾收集器是什么?

JVM那點事-垃圾收集算法講了GC垃圾回收算法臀晃,即(分代收集算法[復(fù)制算法——標記清除/標記整理])觉渴。我們接下來講一下垃圾回收器。下圖展示了不同分代的收集器徽惋,如果兩個收集器之間存在連線案淋,說明他們可以搭配使用。虛擬機所在的區(qū)域寂曹,則表示它是屬于新生代收集器還是老年代收集器哎迄。

HotSpot垃圾回收器的種類.png

1. Serial收集器(單線程收集器)

標簽:新生代收集器 復(fù)制算法 單線程收集器

Serial收集器[?s?ri?l]單線程新生代收集器回右,進行垃圾回收的時候隆圆,Stop the World暫停其他所有的工作線程。對于單個CPU的環(huán)境來說翔烁,簡單而高效渺氧。(虛擬機運行在Client模式下的默認新生代收集器。)

2. ParNew收集器(并行收集器)

標簽:新生代收集器 復(fù)制算法 多線程收集器 CMS默認收集器

ParNew([?p?r])收集器其實就是Serial收集器的多線程版本蹬屹。ParNew是許多運行在Server模式下虛擬機首選的新生代收集器侣背。一個重要原因是:目前除了Serial收集器外,只有它與CMS收集器配合工作慨默。ParNew收集器也是使用-XX:UseConcMarkSweepGC選項的默認收集器贩耐,也可以使用-XX:+UseParNewGC選項強制指定。

ParNew收集器在單個CPU環(huán)境中絕對不會有比Serial收集器更好的效果厦取。默認開啟的收集器線程數(shù)與CPU的數(shù)量相同潮太。可以使用-XX:ParallelGCThreads參數(shù)限制垃圾收集器的線程數(shù)[?p?r?lel]

并行(Parallel):指多條垃圾收集器線程并行工作铡买,但此時用戶線程仍處于等待狀態(tài)更鲁。
并發(fā)(Concurrent):指用戶線程與垃圾回收器同時執(zhí)行(但不一定是并行的,可能會交替運行)奇钞,用戶程序在繼續(xù)運行澡为,而垃圾手機程序運行在另一個CPU上。

3. Parallel Scavenge收集器(并行收集器)

標簽:新生代收集器 復(fù)制算法 多線程收集器 吞吐量優(yōu)先

[?p?r?lel][?sk?v?nd?] 并發(fā)清掃景埃;Parallel Scavenge目標是達到一個可控制的吞吐量媒至。(吞吐量=用戶代碼運行時間/虛擬機運行時間,例如程序運行了100分鐘谷徙,GC占用1分鐘塘慕,那么吞吐量就是99%)

敲黑板,畫重點:面試官問道:“小胖同學(xué)蒂胞,1次10ms的GC和10次1ms的GC图呢,你會選哪種?”)

  • 停頓時間短:適合與 用戶交互的程序骗随,良好的響應(yīng)速度提升用戶體驗阱持。
  • 高吞吐量:適合后臺運算而不需要太多交互的任務(wù),可以高效率利用CPU時間齿诞,盡快完成程序的運行任務(wù).

(小胖內(nèi)心OS:停頓時間1ms麻裳,這么快,一定是垃圾少涨椒,那就是犧牲了新生代空間摊鸡,頻繁GC會導(dǎo)致吞吐量的下降,但是適合用戶交互程序蚕冬,反之免猾,吞吐量大的話,可以高效利用CPU囤热,適合后臺運算的程序猎提。)

Parallel Scavenge收集器提供了兩個參數(shù)用于精確控制吞吐量∨园控制垃圾回收器停頓時間的-XX:MaxGCPauseMills
[p?:z]['m?lz]锨苏。以及設(shè)置吞吐量大小的-XX:GCTimeRatio
不要以為把MaxGCPauseMills參數(shù)設(shè)置小就能使系統(tǒng)垃圾收集速度變快。GC停頓時間縮短是犧牲吞吐量和新生代空間來換取的棺聊。(比如將新生代調(diào)小伞租,原來10s收集一次,每次100ms限佩,葵诈;現(xiàn)在5s收集一次,每次70ms;停頓時間的確下降驯击,但吞吐量也下降了)
GCTimeRatio參數(shù)的值應(yīng)當是[0,100]的整數(shù)烁兰。如果把參數(shù)設(shè)置為19,允許最大的GC時間(1/(1+19))占用總時間的5%

4. Parallel Old收集器(并行收集器)

標簽:老生代收集器 標記-整理算法 多線程收集器 吞吐量優(yōu)先

注重吞吐量以及CPU資源敏感的場合徊都,都可以優(yōu)先考慮Parallel ScavengeParallel Old收集器沪斟。

5. CMS收集器(并發(fā)收集器)

標簽: 老年代收集器 標記-清除算法 低停頓時間 并發(fā)收集器 CPU資源敏感 浮動垃圾 內(nèi)存碎片

CMS(Concurrent Mark Sweep)收集器是一種獲取最短回收停頓時間為目標的收集器。目前很大一部分的java應(yīng)用集中在互聯(lián)網(wǎng)或者B/S系統(tǒng)的服務(wù)端上暇矫。重視響應(yīng)速度主之,希望系統(tǒng)停頓時間最短。

  • 初始標記:標記GC Roots 直接關(guān)聯(lián)的對象(Stop the World)李根。
  • 并發(fā)標記:獲取初始標記的節(jié)點做為根節(jié)點槽奕,并發(fā)標記對象。
  • 重新標記:修正并發(fā)標記過程中變動的對象房轿。如何修改粤攒?就是將并發(fā)標記階段變化的對象記錄在線程Remembered Set Logs線程,在重新標記階段囱持,將數(shù)據(jù)合并到Remember Set中夯接。(PS:詳見G1收集器描述)(Stop the World)
  • 并發(fā)清除并發(fā)清除對象

(原理簡單明了)

其中初始標記重新標記兩個步驟仍然需要Stop The World纷妆。

在Java語言中盔几,可作為GC Roots的對象...

缺點是:

  • 對CPU資源敏感:在并發(fā)階段,雖然不會導(dǎo)致用戶線程停頓掩幢,但是占用線程(CPU資源)導(dǎo)致應(yīng)用程序變慢逊拍。CMS默認啟動的線程數(shù)(CPU+3)/4,也就是當CPU在4個以上時际邻,并發(fā)回收垃圾線程不少于25%的CPU資源芯丧。

  • 浮動垃圾:并發(fā)清理階段用戶線程還在運行,只能下次GC回收枯怖,這些就稱為“浮動垃圾”注整。垃圾收集階段用戶線程還在運行能曾,所以不能等到老年代幾乎填滿在進行收集度硝。要設(shè)置老年代預(yù)留空間,可以設(shè)置-XX:CMSInitiatingOccupancyFranction音標: [?'n???e?t??]初始 [??kj?p?nsi] 居住 [?fr?k?n] 一小部分寿冕,提高觸發(fā)百分比蕊程。在JDK1.6,CMS收集器的啟動闕值92%驼唱。要是CMS運行期間預(yù)留的內(nèi)存無法滿足程序需要藻茂,就會觸發(fā)Concurrent Mode Failure 失敗,虛擬機啟動后備方案,臨時啟動Serial Old收集器來重新進行老年代的垃圾回收辨赐。所以說优俘,參數(shù)-XX:CMSInitiatingOccupancyFranction設(shè)置的太高,容易觸發(fā)Concurrent Mode Failure失敗掀序,性能反而降低帆焕。

  • 內(nèi)存碎片:“標記-清除”算法會產(chǎn)生大量空間碎片!空間碎片過多時不恭,大對象分配帶來麻煩叶雹,導(dǎo)致對象有很大剩余,但是無法找到連續(xù)空間分配對象换吧,提前觸發(fā)full GC折晦。
    可以設(shè)置-XX:UseCMSCompactAtFullCollectionCMS默認開啟。在Full GC的時候采用合并整理過程沾瓦,但是內(nèi)存整理無法并發(fā)會導(dǎo)致停頓時間變長满着。還有一個參數(shù)-XX:CMSFullGCsBeforeCompaction,這個參數(shù)是用于執(zhí)行多少次不壓縮的Full GC跟著來一次壓縮的贯莺。

總結(jié)來說:CMS并發(fā)收集漓滔,低停頓。

  1. 搶占CPU資源乖篷;
  2. 浮動垃圾响驴,并且要為應(yīng)用程序預(yù)留空間,我們可以設(shè)置預(yù)留比例撕蔼,但是預(yù)留比例無法滿足應(yīng)用程序需求時豁鲤,會啟動Serial Old收集器。性能可能下降;
  3. 內(nèi)存碎片鲸沮,可以開啟在清除后合并壓縮琳骡,但是整理階段,無法并發(fā)讼溺。導(dǎo)致停頓時間變長楣号,也可以設(shè)置多次Full GC后壓縮碎片;

5. G1收集器(并發(fā)收集器)

標簽: 分代收集 空間整合 并發(fā)收集 可預(yù)測停頓 內(nèi)存化整為零

G1之前的其他收集器收集的范圍都是新生代或者老年代怒坯。G1將整個Java堆劃分為大小相等的獨立區(qū)域·(region [?ri:d??n])炫狱。新生代老年代不再是物理隔離的了。他們都是一部分的region(不需要連續(xù))的集合剔猿。

G1收集器之所以能建立可預(yù)測的停頓時間模型视译。是因為G1可以跟蹤各個region里面垃圾堆價值大小(回收所獲得的空間以及回收所需的時間經(jīng)驗值)归敬,在后臺維護了優(yōu)先列表酷含。根據(jù)允許的收集時間鄙早,優(yōu)先回收價值最大的Region(劃分空間以及有優(yōu)先級的區(qū)域回收椅亚。PS:G1執(zhí)行的第四步限番,篩選階段,就是根據(jù)用戶期望GC時間呀舔,制定回收計劃0饴啤)

一個對象被分配到region中,他并非只能被region中的其他對象引用别威,而是可以與整個java堆任意對象發(fā)生引用躯舔,那么可達性分析法判定對象是否存活時,豈不是還要掃描整個堆省古?在以前的分代收集中粥庄,新生代中的對象也面臨著相同的問題,Minor GC時若是同時掃描老年代的話豺妓,那么Minor GC效率可能下降不少惜互。

G1垃圾回收是否掃描整個堆,或者minor gc是否掃描整個堆琳拭?

在G1收集器中训堆,Region之間的對象引用以及其他收集器新生代和老年代之間的對象引用。(敲黑板白嘁,劃重點)虛擬機都是使用Remembered Set來避免全堆掃描的坑鱼。

G1中每個region都有一個與之對應(yīng)的Remembered Set,虛擬機發(fā)現(xiàn)程序在對Reference類型的數(shù)據(jù)進行寫操作時絮缅,會產(chǎn)生一個Write Barrier暫停暫時中斷寫操作鲁沥,檢查Reference引用對象是否處于不同的Region之中(分代中就是檢查是否老年代中的對象引用新生代的對象)。如果是耕魄,便通過CardTable把相關(guān)的引用對象所屬的RegionRemembered Set之中画恰,當進行垃圾回收時,在GC Roots中的枚舉范圍中加入Remembered Set即可保證不對全堆掃描也不會有遺漏吸奴。

小胖有話說:虛擬機對引用類型數(shù)據(jù)進行操作時允扇,判斷引用的對象是否處于不同的Rigion區(qū),或者是否是老年代對象引用新生代對象则奥,若是的話考润,則寫入Remembered Set中,GC Roots會在枚舉范圍加入Remembered Set保證不進行全表掃描的情況下不會遺漏對象逞度。

(嘻嘻额划,以后面試官問G1執(zhí)行步驟時,將維護 Remembered Set操作也可以描述一下呀)

G1收集器運作大致可劃分為以下幾個步驟:

  • 初始標記(Initial Marking):暫停線程档泽,標記GC Roots能直接關(guān)聯(lián)到的對象俊戳。

  • 并發(fā)階段(Concurrent Marking):對堆中的對象進行可達性分析,耗時較長馆匿,可并發(fā)執(zhí)行抑胎;

  • 最終階段(Final Marking):修正并發(fā)階段期間用戶程序運行導(dǎo)致標記產(chǎn)生變化的記錄;* (敲黑板渐北,繼續(xù)劃重點)*虛擬機將這段時間對象變化在線程Remembered Set Logs中阿逃,最終階段需要把Remembered Set Logs數(shù)據(jù)合并到Remembered Set中,需要停頓線程赃蛛,但可并行執(zhí)行恃锉。

  • 篩選階段(Live Data Counting and Evacuation):根據(jù)用戶期望的GC停頓時間制定回收計劃。也可做到與用戶程序并行執(zhí)行呕臂。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末破托,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子歧蒋,更是在濱河造成了極大的恐慌土砂,老刑警劉巖,帶你破解...
    沈念sama閱讀 206,311評論 6 481
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件谜洽,死亡現(xiàn)場離奇詭異萝映,居然都是意外死亡,警方通過查閱死者的電腦和手機阐虚,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 88,339評論 2 382
  • 文/潘曉璐 我一進店門序臂,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人实束,你說我怎么就攤上這事贸宏。” “怎么了磕洪?”我有些...
    開封第一講書人閱讀 152,671評論 0 342
  • 文/不壞的土叔 我叫張陵吭练,是天一觀的道長。 經(jīng)常有香客問我析显,道長鲫咽,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 55,252評論 1 279
  • 正文 為了忘掉前任谷异,我火速辦了婚禮分尸,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘歹嘹。我一直安慰自己箩绍,他們只是感情好,可當我...
    茶點故事閱讀 64,253評論 5 371
  • 文/花漫 我一把揭開白布尺上。 她就那樣靜靜地躺著材蛛,像睡著了一般圆到。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上卑吭,一...
    開封第一講書人閱讀 49,031評論 1 285
  • 那天芽淡,我揣著相機與錄音,去河邊找鬼豆赏。 笑死挣菲,一個胖子當著我的面吹牛,可吹牛的內(nèi)容都是我干的掷邦。 我是一名探鬼主播白胀,決...
    沈念sama閱讀 38,340評論 3 399
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼抚岗!你這毒婦竟也來了或杠?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 36,973評論 0 259
  • 序言:老撾萬榮一對情侶失蹤苟跪,失蹤者是張志新(化名)和其女友劉穎廷痘,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體件已,經(jīng)...
    沈念sama閱讀 43,466評論 1 300
  • 正文 獨居荒郊野嶺守林人離奇死亡笋额,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 35,937評論 2 323
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了篷扩。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片兄猩。...
    茶點故事閱讀 38,039評論 1 333
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖鉴未,靈堂內(nèi)的尸體忽然破棺而出枢冤,到底是詐尸還是另有隱情,我是刑警寧澤铜秆,帶...
    沈念sama閱讀 33,701評論 4 323
  • 正文 年R本政府宣布淹真,位于F島的核電站,受9級特大地震影響连茧,放射性物質(zhì)發(fā)生泄漏核蘸。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點故事閱讀 39,254評論 3 307
  • 文/蒙蒙 一啸驯、第九天 我趴在偏房一處隱蔽的房頂上張望客扎。 院中可真熱鬧,春花似錦罚斗、人聲如沸徙鱼。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,259評論 0 19
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽袱吆。三九已至厌衙,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間杆故,已是汗流浹背迅箩。 一陣腳步聲響...
    開封第一講書人閱讀 31,485評論 1 262
  • 我被黑心中介騙來泰國打工溉愁, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留处铛,地道東北人。 一個月前我還...
    沈念sama閱讀 45,497評論 2 354
  • 正文 我出身青樓拐揭,卻偏偏與公主長得像撤蟆,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子堂污,可洞房花燭夜當晚...
    茶點故事閱讀 42,786評論 2 345

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