JVM GC整理

堆內(nèi)存模型

幾種GC

  • Minor/Young GC: 只收集 Young區(qū)的 GC
    每進行一次Young GC酱固,Survivor區(qū)內(nèi)活躍對象將加一歲氧腰,達到一定年齡將移入OLD區(qū)

  • Old GC: 只收集 Old區(qū)的 GC痹升,只有垃圾收集器 CMS 的 concurrent collection 是這個模式

  • Full GC: 收集整個堆拒课,包括新生代鳞骤,老年代探颈,永久代(JDK1.8及以后為 metaspace 元空間)等所有部分的模式

  • Mixed GC: 收集整個 Young Gen 以及部分 old gen 的 GC,只有垃圾收集器 G1 有這個模式

GC時會stop the world

1症杏、避免無法徹底清理干凈
2装获、GC的工作必須在一個能確保一致性的快照中進行

申請內(nèi)存大致過程

1、創(chuàng)建對象后厉颤,將嘗試在Eden申請一片內(nèi)存
2穴豫、若Eden區(qū)內(nèi)存空間足夠,則申請結(jié)束
3逼友、若Eden區(qū)內(nèi)存空間不足精肃,進行YoungGC(觸發(fā)清理YOUNG區(qū)不活躍對象,活躍對象滿足一定條件的晉升到OLD區(qū))
4帜乞、若OLD的空間不足(觸發(fā)閾值或新晉對象等行為導(dǎo)致不足)則觸發(fā)FullGC
5司抱、若FullGC后,Eden區(qū)仍不能滿足申請的內(nèi)存挖函,則觸發(fā)OOM(out of memory)

GC收集算法(GC收集器都是基于這些算法來實現(xiàn))

復(fù)制(Copying)算法

YoungGC基本都是基于該算法状植,所以直接以YoungGC的過程來簡述該算法

假定正在使用的是S0區(qū),S1區(qū)是空閑的
將YOUNG區(qū)中活躍的對象復(fù)制到S1區(qū)(兩個Survivor區(qū)交替使用怨喘,永遠有一個是空的津畸,留給下次復(fù)制)并清理Eden區(qū)和S0區(qū)的對象。若活躍對象大于S1區(qū)時必怜,部分對象將會直接進入OLD區(qū)肉拓,部分仍留在S1區(qū)
缺點:浪費內(nèi)存
優(yōu)點:無內(nèi)存碎片,對象存活率低時效率高于另外幾種
適用:對象存活率低的

標(biāo)記-清除(Mark-Sweep)算法

從根開始標(biāo)記存活的對象梳庆,然后重新掃一遍將未標(biāo)記的對象清除同時清除標(biāo)記
缺點:
產(chǎn)生大量內(nèi)存碎片暖途,容易導(dǎo)致大內(nèi)存對象無足夠空間,提前觸發(fā)GC
效率低(全堆對象遍歷)stop the world的時間比較長

標(biāo)記-整理(Mark-Compact)算法

從根開始標(biāo)記存活的對象膏执,然后整理到一端驻售,其余清除
缺點:效率低(全堆對象遍歷與內(nèi)存整理)
優(yōu)點:有效利用內(nèi)存無碎片

年輕代一般適用復(fù)制算法,年老代一般適用標(biāo)記-整理算法

GC的幾種收集器

GC收集器-有連線的兩種收集器可搭配使用

年輕代收集器

Serial

這是最早的新生代收集器更米,也是jdk1.5之前默認(rèn)的收集器欺栗。它是基于復(fù)制算法實現(xiàn)的,單線程征峦,需要stop the world迟几,所以新生代不能太大,否則對于停頓來講是比較影響交互響應(yīng)的栏笆。
-XX:+UseSerialGC 使用該收集器

Parallel New

-XX:ParallelGCThreads=NNN 來指定 GC 線程數(shù)类腮。 其默認(rèn)值為CPU內(nèi)核數(shù)。

這是對單線程的Serial的一種改進蛉加,ParNew收集器是并行的蚜枢,在多CPU的場景下會有比串行收集器更好的性能,除此之外针饥,實現(xiàn)算法跟Serial完全一樣祟偷。需要注意的是,如果CPU數(shù)量為1個或2個打厘,該種收集器的性能并不會比Serial要好修肠,因為線程之間的切換會產(chǎn)生額外的開銷

Parallel Scavenge

-XX:MaxGCPauseMillis
控制垃圾收集最大停頓時間(毫秒),收集器將盡力保證內(nèi)存回收花費的時間不超過設(shè)定值(設(shè)置過小會導(dǎo)致新生代空間變小户盯,導(dǎo)致GC更頻繁嵌施,總GC時間反而變長、吞吐量下降)

-XX:GCTimeRatio
設(shè)置吞吐量大忻а肌(0-100)吗伤,GC時間 <= 1 / (1 + 吞吐量) * 的系統(tǒng)運行花時間。(-XX:GCTimeRatio=99硫眨,表示GC時間不超過總時間的1%)

-XX:+UseAdaptiveSizePolicy
自適應(yīng)策略開關(guān)開關(guān)參數(shù)足淆,不需要手工指定(-Xmn,-XX:SurvivorRatio、-XX:PretenureSizeThreshold)等細節(jié)參數(shù)了巧号,虛擬機會根據(jù)當(dāng)前系統(tǒng)的運行情況收集性能監(jiān)控信息族奢,動態(tài)調(diào)整這些參數(shù)以提供最合適的停頓時間或最大的吞吐量

采用的也是復(fù)制算法,它與前兩種收集器最大的區(qū)別是丹鸿,它關(guān)注的是吞吐量而不是延遲越走。也被稱為是吞吐量優(yōu)先的收集器。其中靠欢,吞吐量=運行用戶代碼時間/(運行用戶代碼時間+垃圾收集時間)
主要使用場景:主要適合在后臺運算而不是太多交互的任務(wù)廊敌,高吞吐量則可以最高效率的利用CPU時間,盡快的完成程序的運算任務(wù)

年老代收集器

Serial Old

這個是jdk1.2以前的默認(rèn)收集器,使用的是【標(biāo)記-整理】算法门怪,單線程骡澈,stop the world

Parallel Old

Parallel Scavenge的老年代版本,使用的是【標(biāo)記-整理】算法掷空。目前它跟Parallel Scavenge的配合是吞吐量優(yōu)先場景的優(yōu)先選擇秧廉。

CMS

-XX:+UseCMSCompactAtFullCollection,應(yīng)用于在FULL GC后再進行一個碎片整理過程
-XX:+CMSFullGCsBeforeCompaction拣帽,多少次不壓縮的full gc后來一次帶壓縮的
-XX:+UseCMSInitiatingOccupancyOnly=true疼电,使用手動指定回收百分比
-XX:CMSInitiatingOccupancyFraction=92,對內(nèi)存占用率達到92%提前GC(因為CMS產(chǎn)生浮動垃圾)

CMS减拭,Concurrent Mark Sweep蔽豺,這是一款真正的并發(fā)收集器。前面的都是講的并行拧粪。使用的是【標(biāo)記-清除】算法
收集過程:
1修陡、初始標(biāo)記,stop the world可霎,只做GC Root可達性的初始標(biāo)記
2魄鸦、并發(fā)標(biāo)記,并發(fā)執(zhí)行癣朗,進行GCRoots Tracing(可達性分析)過程拾因,時間很長
3、重新標(biāo)記旷余,stop the world绢记,標(biāo)記第二步中變動的對象,時間較長
4正卧、并發(fā)清除蠢熄,并發(fā)執(zhí)行,回收內(nèi)存空間

缺點:
內(nèi)存碎片炉旷,提前觸發(fā)一次full gc
產(chǎn)生浮動垃圾签孔,由于清除是并發(fā)的叉讥,這時用戶產(chǎn)生的垃圾無法在本次收集過程中收集掉

收集器 G1

參考:
詳文
官方
詳文

-XX:+UseG1GC,使用G1收集器
-XX:G1HeapRegionSize饥追,一個Region的大小2的冪
-XX:MaxGCPauseMillis图仓,期望GC停頓時間(毫秒)
-XX:ParallelGCThreads,并行STW的線程數(shù)(與邏輯處理器的數(shù)量相同)
-XX:ConcGCThreads判耕,并行標(biāo)記的線程數(shù)(ParallelGCThreads的1/4)
-XX:InitiatingHeapOccupancyPercent=60,YoungGC后當(dāng)整個堆占用超過60%時翘骂,就會觸發(fā)并發(fā)GC周期
-XX:G1HeapWastePercent=10壁熄,并發(fā)標(biāo)記后可回收的垃圾占比,小于則不回收碳竟,10%
-XX:G1MixedGCCountTarget=8草丧,一個周期內(nèi)觸發(fā)Mixed GC最大次數(shù),8次
-XX:G1NewSizePercent=35莹桅,新生代比例下限昌执,35%
-XX:G1MaxNewSizePercent=60,新生代比例上限诈泼,60%
-XX:MetaspaceSize=256m

G1收集器將內(nèi)存劃分了多個區(qū)域(Region)
區(qū)域的類型有Eden懂拾,Survivor,Old铐达,Humongous岖赋,除了Humongous外,其余和之前介紹的一樣意思
Humongous:用于存放巨型對象(超過Region大小的50%)瓮孙,若一個存不下將找多個連續(xù)的Humongous一起唐断。一開始直接存在Old的空間,但G1有優(yōu)化會在YoungGC對其進行回收(從1.8的某個版本開始)

  • YoungGC
    回收Eden杭抠、Survivor脸甘、Humongous
    由于會回收Humongous,所以O(shè)ld的內(nèi)存空間會有減少偏灿,但并不是回收了Old對象
    調(diào)整eden與old的占比

  • MixedGC
    每當(dāng)YoungGC后會根據(jù)JVM參數(shù)(IHOP等)判斷當(dāng)前是否需要開始進行MixedGC

    MixedGC主要可以分為兩個階段:
    1丹诀、全局并發(fā)標(biāo)記(global concurrent marking)

    全局并發(fā)標(biāo)記又可以進一步細分成下面幾個步驟:

    • 初始標(biāo)記(initial mark,STW)翁垂。它標(biāo)記了從GC Root開始直接可達的對象忿墅。初始標(biāo)記階段借用young GC的暫停,因而沒有額外的沮峡、單獨的暫停階段疚脐。
    • 并發(fā)標(biāo)記(Concurrent Marking)。這個階段從GC Root開始對heap中的對象標(biāo)記邢疙,標(biāo)記線程與應(yīng)用程序線程并行執(zhí)行棍弄,并且收集各個Region的存活對象信息望薄。過程中還會掃描上文中提到的SATB write barrier所記錄下的引用。
    • 最終標(biāo)記(Remark呼畸,STW)痕支。標(biāo)記那些在并發(fā)標(biāo)記階段發(fā)生變化的對象,將被回收蛮原。
    • 清除垃圾(Cleanup卧须,部分STW)。這個階段如果發(fā)現(xiàn)完全沒有活對象的region就會將其整體回收到可分配region列表中儒陨。 清除空Region花嘶。

    2、拷貝存活對象(Evacuation)

    Evacuation階段是全暫停的蹦漠。它負責(zé)把一部分region里的活對象拷貝到空region里去(并行拷貝)椭员,然后回收原本的region的空間。Evacuation階段可以自由選擇任意多個region來獨立收集構(gòu)成收集集合(collection set笛园,簡稱CSet)隘击,CSet集合中Region的選定依賴于上文中提到的停頓預(yù)測模型,該階段并不evacuate所有有活對象的region研铆,只選擇收益高的少量region來evacuate埋同,這種暫停的開銷就可以(在一定范圍內(nèi))可控

  • 錯誤的設(shè)置將會導(dǎo)致無法按期望的進行MixedGC,從而導(dǎo)致FullGC的出現(xiàn)

注意IHOP棵红、G1MaxNewSizePercent莺禁、G1NewSizePercent的關(guān)系
eden的占比要小于1-IHOP才能觸發(fā)MixedGC
(G1NewSizePercent ~ G1MaxNewSizePercent) < 1 - IHOP

已知1
    mixedGC觸發(fā)條件:
        current heap / total heap > IHOP 
        (current eden + current old) / total heap > IHOP
    mixedGC前總是會觸發(fā)YoungGC:
        current eden = 0

    綜上滿足該條件時會觸發(fā)mixedGC:
        current old / total heap > IHOP

已知2
    年老代 = 年老代占比 * 總堆
        total old = (1 - total eden percent) * total heap


假設(shè)期望年老代使用占比達到 A 時觸發(fā)mixedGC,則
    current old = total old * A

將 已知2 代入 假設(shè) 得
    current old = (1 - total eden percent) * total heap * A

再代入 已知1 得
    (1 - total eden percent) * total heap * A / total heap > IHOP

簡化得
    IHOP < (1 - total eden percent) * A

total eden percent 取值范圍: G1NewSizePercent ~ G1MaxNewSizePercent
為保證能正常mixedGC窄赋,total eden percent 取 G1MaxNewSizePercent

最終
    IHOP < (1 - G1MaxNewSizePercent) * A

GC日志

-Xloggc:./tmp/gc-%t.log -XX:+PrintGCDetails -XX:+PrintGCDateStamps
-XX:+PrintGC 輸出GC日志
-XX:+PrintGCDetails 輸出GC的詳細日志
-XX:+PrintGCTimeStamps 輸出GC的時間戳(以基準(zhǔn)時間的形式)
-XX:+PrintGCDateStamps 輸出GC的時間戳(以日期的形式哟冬,如 2013-05-04T21:53:59.234+0800)
-XX:+PrintHeapAtGC 在進行GC的前后打印出堆的信息
-Xloggc:../logs/gc.log 日志文件的輸出路徑

%t 后綴格式生成的時間戳格式為 YYYY-MM-DD_HH-MM-SS。因此忆绰,生成的日志文件名看起來像這樣 gc-2019-01-29_20-41-47.log浩峡。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個濱河市错敢,隨后出現(xiàn)的幾起案子翰灾,更是在濱河造成了極大的恐慌,老刑警劉巖稚茅,帶你破解...
    沈念sama閱讀 221,820評論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件纸淮,死亡現(xiàn)場離奇詭異,居然都是意外死亡亚享,警方通過查閱死者的電腦和手機咽块,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,648評論 3 399
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來欺税,“玉大人侈沪,你說我怎么就攤上這事揭璃。” “怎么了亭罪?”我有些...
    開封第一講書人閱讀 168,324評論 0 360
  • 文/不壞的土叔 我叫張陵瘦馍,是天一觀的道長。 經(jīng)常有香客問我应役,道長情组,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,714評論 1 297
  • 正文 為了忘掉前任箩祥,我火速辦了婚禮院崇,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘滥比。我一直安慰自己亚脆,他們只是感情好做院,可當(dāng)我...
    茶點故事閱讀 68,724評論 6 397
  • 文/花漫 我一把揭開白布盲泛。 她就那樣靜靜地躺著,像睡著了一般键耕。 火紅的嫁衣襯著肌膚如雪寺滚。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,328評論 1 310
  • 那天屈雄,我揣著相機與錄音村视,去河邊找鬼。 笑死酒奶,一個胖子當(dāng)著我的面吹牛蚁孔,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播惋嚎,決...
    沈念sama閱讀 40,897評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼杠氢,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了另伍?” 一聲冷哼從身側(cè)響起鼻百,我...
    開封第一講書人閱讀 39,804評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎摆尝,沒想到半個月后温艇,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,345評論 1 318
  • 正文 獨居荒郊野嶺守林人離奇死亡堕汞,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,431評論 3 340
  • 正文 我和宋清朗相戀三年勺爱,在試婚紗的時候發(fā)現(xiàn)自己被綠了。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片讯检。...
    茶點故事閱讀 40,561評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡邻寿,死狀恐怖蝎土,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情绣否,我是刑警寧澤誊涯,帶...
    沈念sama閱讀 36,238評論 5 350
  • 正文 年R本政府宣布,位于F島的核電站蒜撮,受9級特大地震影響暴构,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜段磨,卻給世界環(huán)境...
    茶點故事閱讀 41,928評論 3 334
  • 文/蒙蒙 一取逾、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧苹支,春花似錦砾隅、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,417評論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至寻定,卻和暖如春儒洛,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背狼速。 一陣腳步聲響...
    開封第一講書人閱讀 33,528評論 1 272
  • 我被黑心中介騙來泰國打工琅锻, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人向胡。 一個月前我還...
    沈念sama閱讀 48,983評論 3 376
  • 正文 我出身青樓恼蓬,卻偏偏與公主長得像,于是被迫代替她去往敵國和親僵芹。 傳聞我的和親對象是個殘疾皇子处硬,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,573評論 2 359

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

  • 一、Java內(nèi)存布局 1淮捆、Java內(nèi)部布局全貌 JVM包含兩個子系統(tǒng)和兩個組件: 兩個子系統(tǒng)為Class load...
    yaco閱讀 4,457評論 1 42
  • 本文主要介紹 JVM和GC解析如有需要郁油,可以參考如有幫助,不忘 點贊 ?創(chuàng)作不易攀痊,白嫖無義桐腌! 一、OOM的認(rèn)識 S...
    碼農(nóng)很低調(diào)閱讀 193評論 0 0
  • JVM內(nèi)存結(jié)構(gòu)簡介(jdk1.8) JVM層的GC調(diào)優(yōu)是生產(chǎn)環(huán)境上必不可少的一個環(huán)節(jié)苟径,因為我們需要確定這個進程可以...
    Lemonrel閱讀 315評論 0 0
  • JVM與調(diào)優(yōu) imooc JVM Markdown JVM的內(nèi)存結(jié)構(gòu) 運行時數(shù)據(jù)區(qū) 程序計數(shù)器PC Regist...
    心釋逍遙lx閱讀 601評論 0 1
  • 我是黑夜里大雨紛飛的人啊 1 “又到一年六月案站,有人笑有人哭,有人歡樂有人憂愁棘街,有人驚喜有人失落蟆盐,有的覺得收獲滿滿有...
    陌忘宇閱讀 8,544評論 28 53