19-案例實戰(zhàn)剖析-日處理上億數(shù)據(jù)的系統(tǒng)內(nèi)存分析和優(yōu)化

1.系統(tǒng)背景

這是當時開發(fā)中遇到的一個真實場景伙单,也是大部分人在開發(fā)項目中有可能會遇到的一些場景,該系統(tǒng)主要是做大數(shù)據(jù)相關(guān)計算分析的哈肖,日處理數(shù)據(jù)量在上億的規(guī)模。這里我們重點針對JVM內(nèi)存的管理來進行模型分析念秧,數(shù)據(jù)的來源獲取主要是MYSQL數(shù)據(jù)庫以及其他數(shù)據(jù)源里提取大量的數(shù)據(jù)淤井,通過加載到JVM內(nèi)存的過程我們來一起分析出現(xiàn)的問題以及如何優(yōu)化解決(如下圖所示):

image
2.生產(chǎn)環(huán)境

這是一套分布式運行系統(tǒng),生產(chǎn)環(huán)境部署了多臺服務(wù)器(每臺4核8G配置)摊趾,每臺機器大概每分鐘負責執(zhí)行100次數(shù)據(jù)提取和計算币狠,每次提取大概1萬條左右的數(shù)據(jù)到內(nèi)存計算,平均每次計算需要耗費10秒左右時間砾层。 JVM內(nèi)存總共分配了4G南捂,堆內(nèi)存占3G甫菠,其中新生代和老年代分別是1.5G的內(nèi)存空間

image
3.過程分析

按照上述的背景和實際生產(chǎn)環(huán)境,那每次1萬條數(shù)據(jù)會占用多少的內(nèi)存空間呢?這里每條數(shù)據(jù)較大吱晒,平均包含20個字段,可以認為每條數(shù)據(jù)大概在1KB左右怠惶。那么1萬條數(shù)據(jù)對應(yīng)就是10MB大小回季。那么運行多久就會導(dǎo)致新生代塞滿呢?

新生代總共分配1.5G秕重,那么Eden區(qū)分配就是1.2G不同,S1和S2區(qū)分別是150MB;如下圖:

image

現(xiàn)在我們可以來手動計算下了溶耘,1次往Eden區(qū)里填充10MB對象二拐,1分鐘讀取100次,也就是差不多1個G凳兵,那也就是1分鐘左右的時候我們的Eden區(qū)就差不多填滿了百新,這個時候如果觸發(fā)Minor GC,我們通過上文學習知道留荔,JVM在執(zhí)行Minor GC之前是會進行一步檢查動作的:老年代可用內(nèi)存空間是否大于新生代全部對象吟孙?如果是第一次運行到這兒,那么我們的老年代是空的聚蝶,也就是有1.5G的空間杰妓,完全是夠用的。

image

這里觸發(fā)Minor GC進行回收碘勉,但是問題在于如何回收呢巷挥?我們重點來看每次任務(wù)計算的耗時是10S,這里差不多有80次的任務(wù)都已經(jīng)執(zhí)行完畢了验靡,還有大概20個任務(wù)正在計算中倍宾,也就是對應(yīng)還有200MB的對象在引用著雏节,這部分對象是不會被回收的,而我們的幸存者區(qū)域最大也就是150MB無法存放下200MB高职,那么根據(jù)我們講過的空間擔保機制钩乍,這200MB對象會直接進入到老年代!

image

由于每一分鐘就會將Eden區(qū)填滿觸發(fā)Minor GC怔锌,也就是每分鐘就會有200MB對象進入到老年代寥粹,那當老年代的內(nèi)存占用的越多后會發(fā)生什么事情呢?比如兩分鐘過去了埃元,這時占用400MB涝涤,那老年代可用空間就只剩1.1G了,那第三分鐘觸發(fā)Minor GC的時候岛杀,一判斷發(fā)現(xiàn)阔拳,老年代剩余空間已小于Eden區(qū)所有對象1.2G大小了,則會走另一條分支的判斷了类嗤,我們可以根據(jù)下圖再來回顧下:

image

先看參數(shù):-XX:-HandlePromotionFailure是否設(shè)置糊肠,當然一般都會設(shè)置,此時會判斷老年代連續(xù)空間是否大于歷史平均晉升老年代對象的大小遗锣,那歷史晉升對象大小都在200MB罪针,很明顯大于,那么JVM會直接進行冒險操作黄伊,觸發(fā)Minor GC的執(zhí)行泪酱,而本次冒險是成功的!新生代依然繼續(xù)晉升200MB對象到老年代还最。

那么當系統(tǒng)運行到第7分鐘的時候墓阀,這時進入到老年代的對象有1.4G了,剩余空間僅剩100MB拓轻!如下圖:

image

系統(tǒng)運行到這兒斯撮,發(fā)現(xiàn)老年代剩余空間已經(jīng)比歷史平均晉升對象大小都要小了,這時會直接觸發(fā)Full GC扶叉!假設(shè)老年代空間都可以被回收勿锅,那么這時老年代對象就完全清除,接著會繼續(xù)進行Minor GC枣氧,200MB對象繼續(xù)進入老年代溢十,又開始重復(fù)循環(huán)執(zhí)行了。

那么按照以上的運行分析达吞,我們可以得出一個結(jié)論就是:系統(tǒng)平均運行7张弛、8分鐘左右就會觸發(fā)一次Full GC的執(zhí)行!而每次一旦Full GC執(zhí)行,就會嚴重影響到系統(tǒng)的運行效率吞鸭,加上該系統(tǒng)的Full GC頻率較高寺董,給用戶帶來的使用感受是非常糟糕的!

4.JVM優(yōu)化

像真實開發(fā)中大家也有很大幾率會遇到類似這樣的情況刻剥,我們應(yīng)該減少Full GC的次數(shù)以及降低它出現(xiàn)的頻率遮咖,甚至不觸發(fā)Full GC,那么如何進行優(yōu)化呢造虏?這也是考驗一個Java程序員的價值體現(xiàn)盯滚。

針對類似的計算系統(tǒng),每次Minor GC的時候酗电,必然會有一部分數(shù)據(jù)沒處理完畢,但是按照現(xiàn)有的內(nèi)存模型内列,我們的幸存者區(qū)域只有150MB是無法滿足200MB對象的存放撵术,因此有必要調(diào)整我們的內(nèi)存比例。

解決方案:

3GB的堆內(nèi)存大小话瞧,我們直接分配2G給新生代嫩与,1G給老年代,這樣Survivor區(qū)的大小就有200MB了每次剛好能存放下MinorGC過后存活的對象了交排。如下圖所示:

image

只要每次Minor GC時200MB存活對象可以存放進Survivor區(qū)划滋,那么等下一次Minor GC時這部分對象對應(yīng)的計算任務(wù)也已經(jīng)結(jié)束,也可以直接進行回收埃篓。

那么接下來我們還是在繼續(xù)模擬跑一次处坪,當Eden區(qū)內(nèi)存已經(jīng)裝滿,此時S0區(qū)也有200MB對象架专,這是觸發(fā)Minor GC的執(zhí)行同窘,200MB正在執(zhí)行的任務(wù)對象(存活對象)直接轉(zhuǎn)移到S1區(qū),回收清空掉Eden區(qū)和S0區(qū)部脚,如下圖:

image

那么通過以上的分析也不免看出想邦,基本上很少會有對象進入到老年代,我們也成功的將幾分鐘一次的Full GC降低到幾個小時一次委刘,大幅度提升了系統(tǒng)的性能丧没,避免了Full GC對系統(tǒng)運行的影響!

當然這里其實還有一個細節(jié)點:就是動態(tài)年齡對象規(guī)則锡移!如果在Survivor空間中相同年齡所有對象大小的總和大于Survivor空間的一半呕童,年齡大于或等于該年齡的對象就可以直接進入老年代,無須等到-XX:MaxTenuringThreshold中要求的年齡淆珊。這里需要結(jié)合自己公司的實際系統(tǒng)分析到底有多少對象是根據(jù)動態(tài)年齡規(guī)則進入到了老年代拉庵,如果要避免因為這項規(guī)則進入老年代,從而觸發(fā)Full GC也可以嘗試調(diào)整Eden區(qū)和Survivor區(qū)的比例,調(diào)整survivor區(qū)的大小钞支。

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末茫蛹,一起剝皮案震驚了整個濱河市,隨后出現(xiàn)的幾起案子烁挟,更是在濱河造成了極大的恐慌婴洼,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,123評論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件撼嗓,死亡現(xiàn)場離奇詭異柬采,居然都是意外死亡,警方通過查閱死者的電腦和手機且警,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,031評論 2 384
  • 文/潘曉璐 我一進店門粉捻,熙熙樓的掌柜王于貴愁眉苦臉地迎上來,“玉大人斑芜,你說我怎么就攤上這事肩刃。” “怎么了杏头?”我有些...
    開封第一講書人閱讀 156,723評論 0 345
  • 文/不壞的土叔 我叫張陵盈包,是天一觀的道長。 經(jīng)常有香客問我醇王,道長呢燥,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 56,357評論 1 283
  • 正文 為了忘掉前任寓娩,我火速辦了婚禮叛氨,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘棘伴。我一直安慰自己力试,他們只是感情好,可當我...
    茶點故事閱讀 65,412評論 5 384
  • 文/花漫 我一把揭開白布排嫌。 她就那樣靜靜地躺著畸裳,像睡著了一般。 火紅的嫁衣襯著肌膚如雪淳地。 梳的紋絲不亂的頭發(fā)上怖糊,一...
    開封第一講書人閱讀 49,760評論 1 289
  • 那天,我揣著相機與錄音颇象,去河邊找鬼伍伤。 笑死,一個胖子當著我的面吹牛遣钳,可吹牛的內(nèi)容都是我干的扰魂。 我是一名探鬼主播,決...
    沈念sama閱讀 38,904評論 3 405
  • 文/蒼蘭香墨 我猛地睜開眼,長吁一口氣:“原來是場噩夢啊……” “哼劝评!你這毒婦竟也來了姐直?” 一聲冷哼從身側(cè)響起,我...
    開封第一講書人閱讀 37,672評論 0 266
  • 序言:老撾萬榮一對情侶失蹤蒋畜,失蹤者是張志新(化名)和其女友劉穎声畏,沒想到半個月后,有當?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體姻成,經(jīng)...
    沈念sama閱讀 44,118評論 1 303
  • 正文 獨居荒郊野嶺守林人離奇死亡插龄,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點故事閱讀 36,456評論 2 325
  • 正文 我和宋清朗相戀三年,在試婚紗的時候發(fā)現(xiàn)自己被綠了科展。 大學時的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片均牢。...
    茶點故事閱讀 38,599評論 1 340
  • 序言:一個原本活蹦亂跳的男人離奇死亡,死狀恐怖才睹,靈堂內(nèi)的尸體忽然破棺而出徘跪,到底是詐尸還是另有隱情,我是刑警寧澤砂竖,帶...
    沈念sama閱讀 34,264評論 4 328
  • 正文 年R本政府宣布,位于F島的核電站鹃答,受9級特大地震影響乎澄,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜测摔,卻給世界環(huán)境...
    茶點故事閱讀 39,857評論 3 312
  • 文/蒙蒙 一置济、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧锋八,春花似錦浙于、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,731評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽。三九已至紊服,卻和暖如春檀轨,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背欺嗤。 一陣腳步聲響...
    開封第一講書人閱讀 31,956評論 1 264
  • 我被黑心中介騙來泰國打工参萄, 沒想到剛下飛機就差點兒被人妖公主榨干…… 1. 我叫王不留,地道東北人煎饼。 一個月前我還...
    沈念sama閱讀 46,286評論 2 360
  • 正文 我出身青樓讹挎,卻偏偏與公主長得像,于是被迫代替她去往敵國和親。 傳聞我的和親對象是個殘疾皇子筒溃,可洞房花燭夜當晚...
    茶點故事閱讀 43,465評論 2 348

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