GC原理和性能調(diào)優(yōu)

正文

本文的內(nèi)容主要如下:

GC 基礎(chǔ)原理素挽,涉及調(diào)優(yōu)目標(biāo)狸驳,GC 事件分類、JVM 內(nèi)存分配策略耙箍、GC 日志分析等

CMS 原理及調(diào)優(yōu)辩昆。

G1 原理及調(diào)優(yōu)

GC 問題排查和解決思路

1. GC 基礎(chǔ)原理

1.1. GC 調(diào)優(yōu)目標(biāo)

大多數(shù)情況下對(duì) Java 程序進(jìn)行 GC 調(diào)優(yōu),主要關(guān)注兩個(gè)目標(biāo):

響應(yīng)速度(Responsiveness):響應(yīng)速度指程序或系統(tǒng)對(duì)一個(gè)請(qǐng)求的響應(yīng)有多迅速

比如遮斥,用戶訂單查詢響應(yīng)時(shí)間扇丛,對(duì)響應(yīng)速度要求很高的系統(tǒng),較大的停頓時(shí)間是不可接受的较屿。調(diào)優(yōu)的重點(diǎn)是在短的時(shí)間內(nèi)快速響應(yīng)卓练。

吞吐量(Throughput):吞吐量關(guān)注在一個(gè)特定時(shí)間段內(nèi)應(yīng)用系統(tǒng)的最大工作量

例如每小時(shí)批處理系統(tǒng)能完成的任務(wù)數(shù)量,在吞吐量方面優(yōu)化的系統(tǒng)嘱么,較長(zhǎng)的 GC 停頓時(shí)間也是可以接受的顽悼,因?yàn)楦咄掏铝繎?yīng)用更關(guān)心的是如何盡可能快地完成整個(gè)任務(wù),不考慮快速響應(yīng)用戶請(qǐng)求

在 GC 調(diào)優(yōu)中冰评,GC 導(dǎo)致的應(yīng)用暫停時(shí)間影響系統(tǒng)響應(yīng)速度木羹,GC 處理線程的 CPU 使用率影響系統(tǒng)吞吐量解孙。

1.2. GC 分代收集算法

現(xiàn)代的垃圾收集器基本都是采用分代收集算法抛人,其主要思想: 將 Java 的堆內(nèi)存邏輯上分成兩塊:新生代、老年代廷臼,針對(duì)不同存活周期盅惜、不同大小的對(duì)象采取不同的垃圾回收策略忌穿。


1.2.1. 新生代(Young Generation)

新生代又叫年輕代掠剑,大多數(shù)對(duì)象在新生代中被創(chuàng)建,很多對(duì)象的生命周期很短井佑。每次新生代的垃圾回收(又稱 Young GC眠寿、Minor GC、YGC)后只有少量對(duì)象存活盒发,所以使用復(fù)制算法狡逢,只需少量的復(fù)制操作成本就可以完成回收。

**新生代內(nèi)又分三個(gè)區(qū):**一個(gè) Eden 區(qū)蛮艰,兩個(gè) Survivor 區(qū)(S0雀彼、S1,又稱From Survivor仍律、To Survivor)实柠,大部分對(duì)象在 Eden 區(qū)中生成。

當(dāng) Eden 區(qū)滿時(shí)草则,還存活的對(duì)象將被復(fù)制到兩個(gè) Survivor 區(qū)(中的一個(gè));當(dāng)這個(gè) Survivor 區(qū)滿時(shí)炕横,此區(qū)的存活且不滿足晉升到老年代條件的對(duì)象將被復(fù)制到另外一個(gè) Survivor 區(qū)份殿。對(duì)象每經(jīng)歷一次復(fù)制,年齡加 1卿嘲,達(dá)到晉升年齡閾值后拾枣,轉(zhuǎn)移到老年代。

1.2.2. 老年代(Old Generation)

在新生代中經(jīng)歷了 N 次垃圾回收后仍然存活的對(duì)象梅肤,就會(huì)被放到老年代姨蝴,該區(qū)域中對(duì)象存活率高。老年代的垃圾回收通常使用“標(biāo)記-整理”算法吨些。

1.3. GC 事件分類

根據(jù)垃圾收集回收的區(qū)域不同炒辉,垃圾收集主要分為:

Young GC

Old GC

Full GC

Mixed GC

1.3.1. Young GC

新生代內(nèi)存的垃圾收集事件稱為 Young GC(又稱 Minor GC),當(dāng) JVM 無法為新對(duì)象分配在新生代內(nèi)存空間時(shí)總會(huì)觸發(fā) Young GC偶器。比如 Eden 區(qū)占滿時(shí)缝裤,新對(duì)象分配頻率越高,Young GC 的頻率就越高霎苗。

Young GC 每次都會(huì)引起全線停頓(Stop-The-World)榛做,暫停所有的應(yīng)用線程,停頓時(shí)間相對(duì)老年代 GC 造成的停頓趣苏,幾乎可以忽略不計(jì)。

1.3.2. Old GC/Full GC/Mixed GC

Old GC:只清理老年代空間的 GC 事件,只有 CMS 的并發(fā)收集是這個(gè)模式昂灵。

Full GC:清理整個(gè)堆的 GC 事件舞萄,包括新生代、老年代撑螺、元空間等 把还。

Mixed GC:清理整個(gè)新生代以及部分老年代的 GC茸俭,只有 G1 有這個(gè)模式调鬓。

1.4. GC 日志分析

GC 日志是一個(gè)很重要的工具,它準(zhǔn)確記錄了每一次的 GC 的執(zhí)行時(shí)間和執(zhí)行結(jié)果腾窝,通過分析 GC 日志可以調(diào)優(yōu)堆設(shè)置和 GC 設(shè)置虹脯,或者改進(jìn)應(yīng)用程序的對(duì)象分配模式。

開啟的 JVM 啟動(dòng)參數(shù)如下:

-verbose:gc -XX:+PrintGCDetails -XX:+PrintGCDateStamps? -XX:+PrintGCTimeStamps復(fù)制代碼

常見的 Young GC唇敞、Full GC 日志含義如下:

Young GC

Full GC

免費(fèi)的 GC 日志圖形分析工具推薦下面 2 個(gè):

GCViewer:下載 jar 包直接運(yùn)行

gceasy:Web 工具疆柔,上傳 GC 日志在線使用

1.5. 內(nèi)存分配策略

Java 提供的自動(dòng)內(nèi)存管理镶柱,可以歸結(jié)為解決了對(duì)象的內(nèi)存分配和回收的問題。前面已經(jīng)介紹了內(nèi)存回收鞋屈,下面介紹幾條最普遍的內(nèi)存分配策略:

1.5.1. 對(duì)象優(yōu)先在 Eden 區(qū)分配

大多數(shù)情況下,對(duì)象在先新生代 Eden 區(qū)中分配湖蜕。當(dāng) Eden 區(qū)沒有足夠空間進(jìn)行分配時(shí)宋列,虛擬機(jī)將發(fā)起一次 Young GC。

1.5.2. 大對(duì)象直接進(jìn)入老年代

JVM 提供了一個(gè)對(duì)象大小閾值參數(shù)(-XX:PretenureSizeThreshold灭返,默認(rèn)值為 0坤邪,代表不管多大都是先在 Eden 中分配內(nèi)存)。

大于參數(shù)設(shè)置的閾值值的對(duì)象直接在老年代分配怎静,這樣可以避免對(duì)象在 Eden 及兩個(gè) Survivor 直接發(fā)生大內(nèi)存復(fù)制黔衡。

1.5.3. 長(zhǎng)期存活的對(duì)象進(jìn)入老年代

對(duì)象每經(jīng)歷一次垃圾回收,且沒被回收掉夜牡,它的年齡就增加 1侣签,大于年齡閾值參數(shù)(-XX:MaxTenuringThreshold,默認(rèn) 15)的對(duì)象蹦肴,將晉升到老年代中猴娩。

1.5.4. 空間分配擔(dān)保

當(dāng)進(jìn)行 Young GC 之前,JVM 需要預(yù)估:老年代是否能夠容納 Young GC 后新生代晉升到老年代的存活對(duì)象胀溺,以確定是否需要提前觸發(fā) GC 回收老年代空間,基于空間分配擔(dān)保策略來計(jì)算背零。


Young GC 之后如果成功(Young GC 后晉升對(duì)象能放入老年代)无埃,則代表擔(dān)保成功,不用再進(jìn)行 Full GC侦镇,提高性能壳繁。

如果失敗,則會(huì)出現(xiàn)“promotion failed”錯(cuò)誤闹炉,代表擔(dān)保失敗渣触,需要進(jìn)行 Full GC。

1.5.5. 動(dòng)態(tài)年齡判定

新生代對(duì)象的年齡可能沒達(dá)到閾值(MaxTenuringThreshold 參數(shù)指定)就晉升老年代皂冰。

如果 Young GC 之后养篓,新生代存活對(duì)象達(dá)到相同年齡所有對(duì)象大小的總和大于任意? Survivor 空間(S0+S1空間)的一半,此時(shí) S0 或者 S1 區(qū)即將容納不了存活的新生代對(duì)象剔应。年齡大于或等于該年齡的對(duì)象就可以直接進(jìn)入老年代语御,無須等到 MaxTenuringThreshold 中要求的年齡席怪。

另外,如果 Young GC 后 S0 或 S1 區(qū)不足以容納:未達(dá)到晉升老年代條件的新生代存活對(duì)象碉纺,會(huì)導(dǎo)致這些存活對(duì)象直接進(jìn)入老年代刻撒,需要盡量避免。

2. CMS 原理及調(diào)優(yōu)

2.1. 術(shù)語解釋

2.1.1. 可達(dá)性分析算法

用于判斷對(duì)象是否存活态贤,基本思想是通過一系列稱為“GC Root”的對(duì)象作為起點(diǎn)(常見的 GC Root 有系統(tǒng)類加載器醋火、棧中的對(duì)象、處于激活狀態(tài)的線程等)柿冲,基于對(duì)象引用關(guān)系假抄,從 GC Roots 開始向下搜索,所走過的路徑稱為引用鏈宿饱,當(dāng)一個(gè)對(duì)象到 GC Root 沒有任何引用鏈相連刑棵,證明對(duì)象不再存活。

2.1.2. Stop The World

GC 過程中分析對(duì)象引用關(guān)系蛉签,為了保證分析結(jié)果的準(zhǔn)確性碍舍,需要通過停頓所有 Java 執(zhí)行線程,保證引用關(guān)系不再動(dòng)態(tài)變化妈经,該停頓事件稱為 Stop The World(STW)捧书。

2.1.3. Safepoint

代碼執(zhí)行過程中的一些特殊位置,當(dāng)線程執(zhí)行到這些位置的時(shí)候爆哑,說明虛擬機(jī)當(dāng)前的狀態(tài)是安全的舆吮,如果有需要 GC,線程可以在這個(gè)位置暫停潭袱。

HotSpot 采用主動(dòng)中斷的方式锋恬,讓執(zhí)行線程在運(yùn)行期輪詢是否需要暫停的標(biāo)志,若需要?jiǎng)t中斷掛起趟径。

2.2. CMS 算法簡(jiǎn)介

CMS(Concurrent Mark and Sweep 并發(fā)-標(biāo)記-清除)蜗巧,是一款基于并發(fā)、使用標(biāo)記清除算法的垃圾回收算法幕屹,只針對(duì)老年代進(jìn)行垃圾回收望拖。

CMS 收集器工作時(shí),盡可能讓 GC 線程和用戶線程并發(fā)執(zhí)行说敏,以達(dá)到降低 STW 時(shí)間的目的盔沫。

通過以下命令行參數(shù),啟用 CMS 垃圾收集器:

-XX:+UseConcMarkSweepGC復(fù)制代碼

值得補(bǔ)充的是拟淮,下面介紹到的 CMS GC 是指老年代的 GC谴忧,而 Full GC 指的是整個(gè)堆的 GC 事件,包括新生代委造、老年代搏屑、元空間等粉楚,兩者有所區(qū)分模软。

2.3. 新生代垃圾回收

能與 CMS 搭配使用的新生代垃圾收集器有 Serial 收集器和 ParNew 收集器。

這 2 個(gè)收集器都采用標(biāo)記復(fù)制算法携狭,都會(huì)觸發(fā) STW 事件回俐,停止所有的應(yīng)用線程稀并。不同之處在于碘举,Serial 是單線程執(zhí)行搁廓,ParNew 是多線程執(zhí)行。

作者:零壹技術(shù)棧

鏈接:https://juejin.cn/post/6844903953415536654

來源:稀土掘金

著作權(quán)歸作者所有蝙场。商業(yè)轉(zhuǎn)載請(qǐng)聯(lián)系作者獲得授權(quán)粱年,非商業(yè)轉(zhuǎn)載請(qǐng)注明出處台诗。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市嗜憔,隨后出現(xiàn)的幾起案子氏仗,更是在濱河造成了極大的恐慌,老刑警劉巖呐舔,帶你破解...
    沈念sama閱讀 222,464評(píng)論 6 517
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珊拼,死亡現(xiàn)場(chǎng)離奇詭異流炕,居然都是意外死亡每辟,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 95,033評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門妹蔽,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人编整,你說我怎么就攤上這事乳丰〕伤遥” “怎么了?”我有些...
    開封第一講書人閱讀 169,078評(píng)論 0 362
  • 文/不壞的土叔 我叫張陵断箫,是天一觀的道長(zhǎng)秋冰。 經(jīng)常有香客問我剑勾,道長(zhǎng),這世上最難降的妖魔是什么虽另? 我笑而不...
    開封第一講書人閱讀 59,979評(píng)論 1 299
  • 正文 為了忘掉前任捂刺,我火速辦了婚禮族展,結(jié)果婚禮上仪缸,老公的妹妹穿的比我還像新娘。我一直安慰自己,他們只是感情好刻炒,可當(dāng)我...
    茶點(diǎn)故事閱讀 69,001評(píng)論 6 398
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著拇厢,像睡著了一般孝偎。 火紅的嫁衣襯著肌膚如雪寺旺。 梳的紋絲不亂的頭發(fā)上势决,一...
    開封第一講書人閱讀 52,584評(píng)論 1 312
  • 那天陈莽,我揣著相機(jī)與錄音走搁,去河邊找鬼迈窟。 笑死,一個(gè)胖子當(dāng)著我的面吹牛兵琳,可吹牛的內(nèi)容都是我干的骇径。 我是一名探鬼主播破衔,決...
    沈念sama閱讀 41,085評(píng)論 3 422
  • 文/蒼蘭香墨 我猛地睜開眼晰筛,長(zhǎng)吁一口氣:“原來是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來了曙博?” 一聲冷哼從身側(cè)響起怜瞒,我...
    開封第一講書人閱讀 40,023評(píng)論 0 277
  • 序言:老撾萬榮一對(duì)情侶失蹤般哼,失蹤者是張志新(化名)和其女友劉穎蒸眠,沒想到半個(gè)月后杆融,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,555評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡蒋腮,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,626評(píng)論 3 342
  • 正文 我和宋清朗相戀三年池摧,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了险绘。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片誉碴。...
    茶點(diǎn)故事閱讀 40,769評(píng)論 1 353
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡黔帕,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出成黄,到底是詐尸還是另有隱情呐芥,我是刑警寧澤,帶...
    沈念sama閱讀 36,439評(píng)論 5 351
  • 正文 年R本政府宣布奋岁,位于F島的核電站思瘟,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏闻伶。R本人自食惡果不足惜滨攻,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 42,115評(píng)論 3 335
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望蓝翰。 院中可真熱鬧光绕,春花似錦、人聲如沸畜份。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,601評(píng)論 0 25
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽停蕉。三九已至愕鼓,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谷徙,已是汗流浹背拒啰。 一陣腳步聲響...
    開封第一講書人閱讀 33,702評(píng)論 1 274
  • 我被黑心中介騙來泰國(guó)打工驯绎, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留完慧,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,191評(píng)論 3 378
  • 正文 我出身青樓剩失,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親拴孤。 傳聞我的和親對(duì)象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,781評(píng)論 2 361

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