26-JVM優(yōu)化到底優(yōu)化什么?

通過前兩個系列我們把JVM相關(guān)的一些原理內(nèi)容并結(jié)合一些案例和GC工作原理給大家都介紹清楚了,那么本系列開始重點給大家?guī)鞪VM優(yōu)化相關(guān)內(nèi)容和實戰(zhàn)。

基于JVM系統(tǒng)運行的過程剖析

首先我們還是通過一步一圖的方式但校,將我們整個系統(tǒng)基于JVM跑起來后所涉及到的一些核心知識進行串聯(lián)以及總結(jié)回顧,這樣大家在頭腦里先有一個整體的思維過程啡氢,加深印象状囱,然后我們再結(jié)合一些案例來逐步講解如何針對一些系統(tǒng)進行優(yōu)化。

①對象進年輕代

系統(tǒng)啟動后空执,肯定會創(chuàng)建對象浪箭,對象肯定存在我們的JVM內(nèi)存,而且會分配到年輕代的Eden區(qū)中:

image

②年輕代裝滿觸發(fā)GC

當(dāng)系統(tǒng)不斷運行辨绊,對象越來越多奶栖,導(dǎo)致Eden無法裝下,那么就會觸發(fā)年輕代垃圾回收门坷,年輕代主要通過復(fù)制算法進行回收宣鄙。

那么如何進行復(fù)制呢?首先會通過可達性分析算法來標記哪些對象是GC Roots的默蚌,能被當(dāng)做GC ROOTS對象的一般兩種:

  • 方法內(nèi)的局部變量
  • 類的靜態(tài)變量

JVM會將存活的對象統(tǒng)一拷貝到幸存者區(qū)域也就是Survivor冻晤,占年輕代內(nèi)存的10%,如下圖:

image

注意:新生代一旦發(fā)生GC绸吸,那么必定會導(dǎo)致“Stop the World”鼻弧,以后簡稱 STW,讓系統(tǒng)停止運行锦茁。

③年輕代垃圾回收

此時垃圾回收線程開始工作攘轩,這里我們默認使用并發(fā)收集器 ParNew

image

④思考:年輕代GC回收對系統(tǒng)影響大不?

年輕代的GC回收基于復(fù)制算法码俩,一般這個過程都會非常的快度帮,比如幾十ms即可回收完畢,但是大家要注意的一點就是,年輕代的回收是會觸發(fā)STW笨篷,讓系統(tǒng)停止的瞳秽,不過一般我們實際線上部署,機器配置都是2核4G或4核8G率翅,只要給堆內(nèi)存分配的空間足夠练俐,一般來講不需要對年輕代的gc進行調(diào)優(yōu)。大多數(shù)情況下的系統(tǒng)冕臭,一般也就幾分鐘或者幾十分鐘才會進行一次新生代的GC痰洒,卡頓時間也較少,對于用戶而言幾乎沒有太大的感覺浴韭。

那么什么時候需要關(guān)注新生代的GC調(diào)優(yōu)呢丘喻?

當(dāng)我們系統(tǒng)部署在大內(nèi)存機器上的時候,比如32核64G的機器念颈,此時可能年輕代的內(nèi)存就會分配到40G泉粉!比如像Kafka、Elasticsearch之類的大數(shù)據(jù)系統(tǒng)榴芳,都是部署在這種大內(nèi)存的機器嗡靡,而且并發(fā)訪問量相當(dāng)高,那么有可能我們的Eden區(qū)1分鐘就會裝滿窟感,然后觸發(fā)一次MinorGC讨彼,而我們的年輕代基于復(fù)制算法,這個過程由于對象太龐大柿祈,標記復(fù)制也是需要耗費一定的時間哈误,像這樣大的內(nèi)存產(chǎn)生的對象可能回收就得要幾秒鐘,那么就會導(dǎo)致一個可怕的現(xiàn)象:系統(tǒng)每運行1分鐘就會導(dǎo)致卡死幾秒躏嚎,而我們的前端請求一般可能在2秒內(nèi)無響應(yīng)就直接反饋給用戶了蜜自,這種體驗肯定是相當(dāng)不好的。

如何解決大內(nèi)存機器的年輕代GC過慢問題卢佣?

答案就是:使用G1垃圾回收器

由于G1收集器可以設(shè)置一個停頓的時間重荠,比如默認200ms,那么基于G1收集器回收的特點虚茶,我們就可以讓系統(tǒng)每隔200ms就進行一次垃圾回收戈鲁,這樣可以讓我們的系統(tǒng)幾乎在不受影響的情況下,邊執(zhí)行邊回收垃圾嘹叫,同時也不會給用戶帶來卡頓的使用體驗婆殿。

因此小結(jié)下:對于年輕代的垃圾回收,一般不存在太大的問題待笑,對于大內(nèi)存機器我們使用G1回收期即可鸣皂,而我們更多需要關(guān)注和調(diào)優(yōu)的地方在于老年代抓谴!

⑤對象進老年代

首先 我們重新梳理下對象要進入老年代的幾個條件:

  1. 對象在新生代中熬過15次GC暮蹂,年齡達15歲進入老年代寞缝,這種對象一般較少一般都是系統(tǒng)中確實需要長期存在的核心組件。

  2. 動態(tài)年齡判斷規(guī)則仰泻,比如一次GC過后荆陆,Survivor區(qū)中的幾個年齡對象加起來超過Survivor區(qū)內(nèi)存的50%,比如年齡1 + 年齡2 + 年齡3的對象總和超過50%Survivor區(qū)集侯,此時就會把年齡3以上的對象放入老年代被啼。

    這里補充說明下動態(tài)年齡規(guī)則判斷算法:Survivor區(qū)中的對象年齡從小到大進行累加,當(dāng)累加到X年齡時的總和大于50%(可以通過參數(shù) -XX:TargetSurvivorRatio=?來設(shè)置保留多少空間空間棠枉,默認值是50)浓体,那么比X大的都會進入老年代

  3. 大對象直接進老年代,可以通過參數(shù)-XX:PretenureSizeThreshold參數(shù) 設(shè)置

  4. 新生代垃圾回中存活對象太多無法放入Survivor中辈讶,通過空間擔(dān)保原則進入老年代

如果Survivor區(qū)空間太小命浴,就會導(dǎo)致我們以上的條件2和4頻繁發(fā)生,然后導(dǎo)致大量對象進入老年代贱除,從而頻繁觸發(fā)老年代的垃圾回收生闲。

image

當(dāng)然CMS的老年代回收,包括:初始標記月幌、并發(fā)標記碍讯、重新標記、并發(fā)清理扯躺、碎片整理等環(huán)節(jié)捉兴,如果有同學(xué)已經(jīng)忘記了請查看之前的CMS收集器內(nèi)容進行復(fù)習(xí)。

這里重點想說的是录语,一旦觸發(fā)老年代GC那么耗時至少比新生代GC慢10倍以上轴术,因此一旦JVM內(nèi)存分配不合理,導(dǎo)致頻繁觸發(fā)老年代CG對于系統(tǒng)用戶來說就是糟糕的體驗钦无。

因此我們常說的JVM優(yōu)化逗栽,到底在優(yōu)化什么?失暂?

你的代碼編寫是否有問題彼宠,內(nèi)存分配,參數(shù)設(shè)置是否合理弟塞,有沒有導(dǎo)致對象頻繁的進入老年代凭峡,然后頻繁觸發(fā)老年代GC,導(dǎo)致系統(tǒng)頻繁的每隔幾分鐘就要卡死幾秒决记!那么JVM性能優(yōu)化也就是優(yōu)化這些東西摧冀,盡量減少觸發(fā)老年代的GC這就是我們的目標。

⑥Yong GC/Minor GC 觸發(fā)時機

新生代的GC觸發(fā)相信大家應(yīng)該很熟悉了,一旦當(dāng)Eden區(qū)滿了后就會觸發(fā)索昂,并且采用復(fù)制算法來回收建车。

⑦OldGC和Full GC觸發(fā)時機

第一種情況:
老年代連續(xù)空間小于新生代歷次YongGC晉升到老年代的對象的平均值

之前針對老年代的空間擔(dān)保原則時我們畫過一張詳細的圖非常清晰,我們再次拿來回顧下:

image
JVM在Minor GC之前椒惨,當(dāng)判斷到老年代的可用內(nèi)存已經(jīng)小于新生代的全部對象大小缤至,會看一個參數(shù):“-XX:HandlePromotionFailure”是否設(shè)置了。如果有該參數(shù)的設(shè)置康谆,那會繼續(xù)檢查老年代最大可用的連續(xù)空間是否大于歷次晉升到老年代對象的平均大小领斥。當(dāng)判斷到歷次平均大小是小于老年代可用內(nèi)存空間的,將嘗試進行一次Minor GC沃暗,盡管這次Minor GC是有風(fēng)險的月洛;如果小于,或者-XX:HandlePromotionFailure沒有設(shè)置孽锥,那這時就要改為進行一次Full GC膊存。

注意這里為什么執(zhí)行的是Full GC呢而不是Old GC,理論上來說就是Old GC忱叭,只不過當(dāng)Old GC執(zhí)行完了后肯定還會執(zhí)行一次Yong GC隔崎,所以我們直接用了Full GC進行表示。

而且我們之前也明確說明了是在發(fā)生Minor GC之前對上述流程的一個判斷韵丑,因此其實不管最終走不走Old GC爵卒,最后都會執(zhí)行一次Minor GC,前提是沒有發(fā)生OOM異常撵彻。

第二種情況:

執(zhí)行YongGC之后钓株,有一批對象需要放入老年代,而此時老年代沒有足夠的內(nèi)存空間存放陌僵,此時必須觸發(fā)一次Old GC轴合。

就像上圖中所示一樣,假如JVM開啟冒險模式進行一次YongGC碗短,但是執(zhí)行完后了后發(fā)現(xiàn)老年代空間還是不足與存放受葛,那么此時必然觸發(fā)Old GC的執(zhí)行。

第三種情況:

當(dāng)老年代內(nèi)存使用超過了92%偎谁,也要直接觸發(fā)Old GC总滩,當(dāng)然這個比例是可以通過參數(shù)調(diào)整的。

總結(jié)一下就是:當(dāng)老年代空間不足巡雨,沒法放入更多的對象時闰渔,就會觸發(fā)Old GC進行垃圾回收。

其實大家也發(fā)現(xiàn)了铐望,我們上述在分析老年代垃圾回收的觸發(fā)時機時冈涧,也能知曉茂附,要么先進行新生代回收,再觸發(fā)老年代回收督弓,要么老年代回收后也會觸發(fā)一次MinorGC营曼。其實當(dāng)上述條件達到觸發(fā)的就是Full GC了,而不是單純的Old GC咽筋。在后續(xù)的實操案例中我們也可以通過日志觀察到,GC日志中顯示的就是Full GC徊件,而不是單純的Old GC奸攻,F(xiàn)ull GC的觸發(fā)是包含Yong GC,Old GC,永久代的GC。

一般來講永久代的空間都是足夠的虱痕,不會存在太多的垃圾睹耐,里面都是存放的一些常量池之類的數(shù)據(jù),并且StringTable從JDK7開始也移動到了堆內(nèi)存部翘,因此永久代一般來說可回收的垃圾很少硝训,如果真的出現(xiàn)了永久代滿了,那么系統(tǒng)也就直接OOM了新思。

如果大家能將以上內(nèi)容完全掌握理解窖梁,那么我相信大家的JVM理論核心知識點已經(jīng)掌握的非常不錯了!

后續(xù)我們結(jié)合一些工具和實操案例夹囚,或者結(jié)合各位自己當(dāng)下公司的系統(tǒng)來進行JVM調(diào)優(yōu)纵刘,分析,大家一定能徹底的將JVM給熟練于心荸哟,并且不會輕易忘記假哎,如果每次問到你JVM相關(guān)內(nèi)容,你還需要去看看筆記或者博客鞍历,說明當(dāng)時理解清楚了舵抹,并沒有實際運用到公司中。因此劣砍,后續(xù)的一些實際案例希望大家能結(jié)合自己的系統(tǒng)多去思考惧蛹,實操練習(xí)!

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末刑枝,一起剝皮案震驚了整個濱河市赊淑,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌仅讽,老刑警劉巖陶缺,帶你破解...
    沈念sama閱讀 221,198評論 6 514
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異洁灵,居然都是意外死亡饱岸,警方通過查閱死者的電腦和手機掺出,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,334評論 3 398
  • 文/潘曉璐 我一進店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來苫费,“玉大人汤锨,你說我怎么就攤上這事“倏颍” “怎么了闲礼?”我有些...
    開封第一講書人閱讀 167,643評論 0 360
  • 文/不壞的土叔 我叫張陵,是天一觀的道長铐维。 經(jīng)常有香客問我柬泽,道長,這世上最難降的妖魔是什么嫁蛇? 我笑而不...
    開封第一講書人閱讀 59,495評論 1 296
  • 正文 為了忘掉前任锨并,我火速辦了婚禮,結(jié)果婚禮上睬棚,老公的妹妹穿的比我還像新娘第煮。我一直安慰自己,他們只是感情好抑党,可當(dāng)我...
    茶點故事閱讀 68,502評論 6 397
  • 文/花漫 我一把揭開白布包警。 她就那樣靜靜地躺著,像睡著了一般底靠。 火紅的嫁衣襯著肌膚如雪揽趾。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 52,156評論 1 308
  • 那天苛骨,我揣著相機與錄音篱瞎,去河邊找鬼。 笑死痒芝,一個胖子當(dāng)著我的面吹牛俐筋,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播严衬,決...
    沈念sama閱讀 40,743評論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼澄者,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了请琳?” 一聲冷哼從身側(cè)響起粱挡,我...
    開封第一講書人閱讀 39,659評論 0 276
  • 序言:老撾萬榮一對情侶失蹤,失蹤者是張志新(化名)和其女友劉穎俄精,沒想到半個月后询筏,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 46,200評論 1 319
  • 正文 獨居荒郊野嶺守林人離奇死亡竖慧,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 38,282評論 3 340
  • 正文 我和宋清朗相戀三年嫌套,在試婚紗的時候發(fā)現(xiàn)自己被綠了逆屡。 大學(xué)時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點故事閱讀 40,424評論 1 352
  • 序言:一個原本活蹦亂跳的男人離奇死亡踱讨,死狀恐怖魏蔗,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情痹筛,我是刑警寧澤莺治,帶...
    沈念sama閱讀 36,107評論 5 349
  • 正文 年R本政府宣布,位于F島的核電站帚稠,受9級特大地震影響谣旁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜翁锡,卻給世界環(huán)境...
    茶點故事閱讀 41,789評論 3 333
  • 文/蒙蒙 一蔓挖、第九天 我趴在偏房一處隱蔽的房頂上張望夕土。 院中可真熱鬧馆衔,春花似錦、人聲如沸怨绣。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,264評論 0 23
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽篮撑。三九已至减细,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間赢笨,已是汗流浹背未蝌。 一陣腳步聲響...
    開封第一講書人閱讀 33,390評論 1 271
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留茧妒,地道東北人萧吠。 一個月前我還...
    沈念sama閱讀 48,798評論 3 376
  • 正文 我出身青樓,卻偏偏與公主長得像桐筏,于是被迫代替她去往敵國和親纸型。 傳聞我的和親對象是個殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點故事閱讀 45,435評論 2 359

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