記一次CPU與內(nèi)存飆高的線上事故

背景介紹

我負(fù)責(zé)一個(gè)物聯(lián)網(wǎng)平臺的開發(fā)與運(yùn)維工作八堡,2020年12月18日的一天兄渺,恰逢周五溶耘,本來以為可以劃劃水就可以過愉快的周末了凳兵,一大早讓我看下昨天的設(shè)備上報(bào)的數(shù)據(jù)情況庐扫,打開瀏覽器輸入網(wǎng)址,無法正常登錄萨醒,提示服務(wù)器內(nèi)部錯(cuò)誤富纸!我心里一想不對呀,本人照看的系統(tǒng)已經(jīng)穩(wěn)定運(yùn)行很長一段時(shí)間了堵漱,怎么會這樣勤庐?都坐下愉镰,不要慌丈探,我們慢慢的來處理。

處理過程

首先辨宠,通過我的FinalShell工具通過ssh登錄服務(wù)器嗤形,一眼就看到了讓我震驚的結(jié)果赋兵,我開始慌了。历造。吭产。

有個(gè)java進(jìn)程居然內(nèi)存和CPU占用都這么高臣淤,然后我簡單看了一下進(jìn)程號邑蒋,定位到是物聯(lián)網(wǎng)平臺的后臺服務(wù)進(jìn)程(由于該平臺是采用docker部署的,因此需要進(jìn)入docker容器內(nèi)部進(jìn)行查看)

https://upload-images.jianshu.io/upload_images/19453215-ad97595918967d4d.png
docker exec -it cfe1916c608a /bin/bash

通過docker exec進(jìn)入容器內(nèi)部寺董,首先還是使用我們比較常用top看下情況

https://upload-images.jianshu.io/upload_images/19453215-7f9790cc733d322e.png

果然覆糟,與我們看到的現(xiàn)象一致,有個(gè)java進(jìn)程RES占有高達(dá)8.6g遮咖,%CPU高達(dá)277.0滩字,這時(shí)突然有些興奮呀,我又可以躺坑了御吞,事后會被作為經(jīng)驗(yàn)文章分享出來麦箍,也就是你現(xiàn)在看到的樣子??。然后我們一步步來分析和處理陶珠。。。

接下來,我們主要從CPU升高的方向先入手分析。復(fù)制該進(jìn)程的id號8,通過執(zhí)行top -Hp查看當(dāng)前進(jìn)程的各個(gè)線程執(zhí)行情況

top -Hp 8
https://upload-images.jianshu.io/upload_images/19453215-89789eb963c20dd3.png

可以看到委刘,前面幾個(gè)線程的CPU占用都非常高漆际,我們隨機(jī)挑選一個(gè)PID為13的線程進(jìn)行分析,需要注意的是,在jstack命令展示中,線程id都是轉(zhuǎn)化成的十六進(jìn)制形式,使用以下命令打印線程id的16進(jìn)制結(jié)果

https://upload-images.jianshu.io/upload_images/19453215-5f78d8f2be21c421.png

重點(diǎn)來了蜒车,執(zhí)行jstack查看堆棧信息情況

jstack 8 |grep d
https://upload-images.jianshu.io/upload_images/19453215-efe9db4efe6a7ffc.png

終于發(fā)現(xiàn)因?yàn)槭裁磳?dǎo)致CPU升高了叛氨,可以看到a,b饭冬,c,d都是代表GC線程(PS:上圖中的10~13這幾個(gè)都是GC線程)冰沙,我們大概猜測應(yīng)該就是因?yàn)镚C進(jìn)行頻繁的垃圾回收侥啤,導(dǎo)致其他業(yè)務(wù)無法正常的工作糠雨。好的,我們還是通過jstat驗(yàn)證一下

jstat -gcutil 8 2000 10 
https://upload-images.jianshu.io/upload_images/19453215-d6642efef381cc11.png

果然邮府,這個(gè)FGC與FGCT顯示的fullGC的次數(shù)和時(shí)間是不是讓你頭皮發(fā)麻 ??。然后,給大家一個(gè)小技巧,我們先通過jmap -histo命令先大致查看下堆內(nèi)存的對象數(shù)量和大小情況

jmap -histo:live 8 | more
https://upload-images.jianshu.io/upload_images/19453215-3f322633bdfa3ef1.png

從分析中我們可以看到【B與【C占有都非常高怜奖,這是什么玩意讹语?其實(shí)這個(gè)Byte和Char數(shù)組才菠,大膽猜測可能是有大量的String字符串渠牲。接奈。。

class name是對象類型遂填,說明如下:

  • B byte
  • C char
  • D double
  • F float
  • I int
  • J long
  • Z boolean
  • [ 數(shù)組客税,如[I表示int[]
  • [L+類名 其他對象

我們還是來好好分析下目胡,到底是什么原因?qū)е碌腉C經(jīng)過這么努力在釋放堆內(nèi)存還是釋放不出來链快,幫幫JVM虛擬機(jī)診斷下病因筑累,這個(gè)時(shí)候其實(shí)大家應(yīng)該已經(jīng)知道我們應(yīng)該看下堆內(nèi)存里面到底是什么

首先,我們通過jmap -dump導(dǎo)出現(xiàn)在JVM的堆內(nèi)存日志情況

jmap -dump:format=b,file=dump.dat 8
https://upload-images.jianshu.io/upload_images/19453215-518353238562a5c9.png

然后茵典,從服務(wù)器下載dump.dat文件到本機(jī),通過Eclipse Memory Analyzer工具對其進(jìn)行分析查看

內(nèi)存使用整體情況

https://upload-images.jianshu.io/upload_images/19453215-97991c5e7f592d62.png

直接點(diǎn)擊下方Reports→Leak Suspects鏈接來生成報(bào)告煮盼,查看導(dǎo)致內(nèi)存泄露的罪魁禍?zhǔn)?/p>

https://upload-images.jianshu.io/upload_images/19453215-7a84e7bb8c8f9c05.png

從圖中可以看出一個(gè)可疑對象消耗了近93.43%的內(nèi)存。接著往下看报破,點(diǎn)擊Details查看詳細(xì)情況

https://upload-images.jianshu.io/upload_images/19453215-66e9da2f19a9badb.png

備注:

Shallow Heap 為對象自身占用的內(nèi)存大小悠就,不包括它引用的對象。

Retained Heap 為當(dāng)前對象大小 + 當(dāng)前對象可直接或間接引用到的對象的大小總和

點(diǎn)擊dominator_tree查看entries heap對象引用關(guān)系tree進(jìn)行分析

https://upload-images.jianshu.io/upload_images/19453215-94e015c3931ffa11.png

最終通過點(diǎn)擊entries引用tree層層查看對象的引用情況泛烙,查看熟悉的東西理卑,定位到好像與device_log_mtu_2020-12這個(gè)地方有關(guān)系

https://upload-images.jianshu.io/upload_images/19453215-3ec62b7110533621.png

其實(shí)我們已經(jīng)大概定位到問題出現(xiàn)位置了翘紊,接下來其實(shí)就要結(jié)合業(yè)務(wù)系統(tǒng)情況來追查業(yè)務(wù)情況與分析系統(tǒng)代碼蔽氨,最終定位到問題的原因:

以下截圖是我與系統(tǒng)的技術(shù)開發(fā)人員的交流,最終大概定位到問題的原因:因?yàn)榇a的邏輯bug導(dǎo)致出現(xiàn)死循環(huán)

https://upload-images.jianshu.io/upload_images/19453215-f9f303b2b939e86c.png

總結(jié)

先通過top命令查看CPU與內(nèi)存情況,查看是什么進(jìn)程的CPU和內(nèi)存飆高鹉究,如果是CPU比較高宇立,則可以通過top -Hp <pid>命令查看當(dāng)前進(jìn)程的各個(gè)線程運(yùn)行情況,找出CPU過高的線程以后自赔,將其線程id轉(zhuǎn)換為十六進(jìn)制的形式后妈嘹,然后通過jstack日志查看改線程的工作狀態(tài)和調(diào)用棧情況,這里有兩種情況:

  1. 如果是正常的用戶線程绍妨,則通過該線程的堆棧信息查看其具體在哪出代碼運(yùn)行比較消耗CPU;
  2. 如果該線程是VM Thread润脸,則通過jstat -gcutil <pid> <period> <times>命令監(jiān)控當(dāng)前系統(tǒng)的GC狀況,然后通過jmap dump:format=b,file=<filepath> <pid>導(dǎo)出系統(tǒng)當(dāng)前的內(nèi)存數(shù)據(jù)他去。導(dǎo)出之后將內(nèi)存情況放到eclipse的mat工具中進(jìn)行分析即可得出內(nèi)存中主要是什么對象比較消耗內(nèi)存毙驯,進(jìn)而可以處理相關(guān)代碼

如果企業(yè)內(nèi)部本身沒有相關(guān)監(jiān)控與運(yùn)維工具,那我們可以使用JDK本身提供了一些監(jiān)控分析工具(jps灾测、jstack爆价、jmap、jhat媳搪、jstat铭段、hprof等),通過靈活運(yùn)用這些工具幾乎能夠定位Java項(xiàng)目80%的性能問題秦爆。最后在這里推薦一個(gè)Alibaba開源的Java診斷工具Arthas可以幫助你解決:

  1. 這個(gè)類從哪個(gè) jar 包加載的序愚?為什么會報(bào)各種類相關(guān)的 Exception?
  2. 我改的代碼為什么沒有執(zhí)行到?難道是我沒 commit?分支搞錯(cuò)了辣辫?
  3. 遇到問題無法在線上 debug善绎,難道只能通過加日志再重新發(fā)布嗎?
  4. 線上遇到某個(gè)用戶的數(shù)據(jù)處理有問題驯绎,但線上同樣無法 debug,線下無法重現(xiàn)!
  5. 是否有一個(gè)全局視角來查看系統(tǒng)的運(yùn)行狀況埂软?
  6. 有什么辦法可以監(jiān)控到JVM的實(shí)時(shí)運(yùn)行狀態(tài)?
  7. 怎么快速定位應(yīng)用的熱點(diǎn)纫事,生成火焰圖勘畔?

參考資料

系統(tǒng)運(yùn)行緩慢,CPU 100%丽惶,以及Full GC次數(shù)過多問題的排查思路

JVM性能調(diào)優(yōu)監(jiān)控工具jps炫七、jstack、jmap钾唬、jhat万哪、jstat侠驯、hprof_憧憬的專欄-CSDN博客

本文由博客一文多發(fā)平臺 OpenWrite 發(fā)布!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末奕巍,一起剝皮案震驚了整個(gè)濱河市吟策,隨后出現(xiàn)的幾起案子,更是在濱河造成了極大的恐慌的止,老刑警劉巖檩坚,帶你破解...
    沈念sama閱讀 211,639評論 6 492
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異诅福,居然都是意外死亡匾委,警方通過查閱死者的電腦和手機(jī),發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,277評論 3 385
  • 文/潘曉璐 我一進(jìn)店門氓润,熙熙樓的掌柜王于貴愁眉苦臉地迎上來剩檀,“玉大人,你說我怎么就攤上這事旺芽』铮” “怎么了?”我有些...
    開封第一講書人閱讀 157,221評論 0 348
  • 文/不壞的土叔 我叫張陵采章,是天一觀的道長运嗜。 經(jīng)常有香客問我,道長悯舟,這世上最難降的妖魔是什么担租? 我笑而不...
    開封第一講書人閱讀 56,474評論 1 283
  • 正文 為了忘掉前任,我火速辦了婚禮抵怎,結(jié)果婚禮上奋救,老公的妹妹穿的比我還像新娘。我一直安慰自己反惕,他們只是感情好尝艘,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,570評論 6 386
  • 文/花漫 我一把揭開白布。 她就那樣靜靜地躺著姿染,像睡著了一般背亥。 火紅的嫁衣襯著肌膚如雪。 梳的紋絲不亂的頭發(fā)上悬赏,一...
    開封第一講書人閱讀 49,816評論 1 290
  • 那天狡汉,我揣著相機(jī)與錄音,去河邊找鬼闽颇。 笑死盾戴,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的兵多。 我是一名探鬼主播尖啡,決...
    沈念sama閱讀 38,957評論 3 408
  • 文/蒼蘭香墨 我猛地睜開眼橄仆,長吁一口氣:“原來是場噩夢啊……” “哼!你這毒婦竟也來了可婶?” 一聲冷哼從身側(cè)響起沿癞,我...
    開封第一講書人閱讀 37,718評論 0 266
  • 序言:老撾萬榮一對情侶失蹤援雇,失蹤者是張志新(化名)和其女友劉穎矛渴,沒想到半個(gè)月后,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體惫搏,經(jīng)...
    沈念sama閱讀 44,176評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡具温,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,511評論 2 327
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了筐赔。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片铣猩。...
    茶點(diǎn)故事閱讀 38,646評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖茴丰,靈堂內(nèi)的尸體忽然破棺而出达皿,到底是詐尸還是另有隱情,我是刑警寧澤贿肩,帶...
    沈念sama閱讀 34,322評論 4 330
  • 正文 年R本政府宣布峦椰,位于F島的核電站,受9級特大地震影響汰规,放射性物質(zhì)發(fā)生泄漏汤功。R本人自食惡果不足惜,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,934評論 3 313
  • 文/蒙蒙 一溜哮、第九天 我趴在偏房一處隱蔽的房頂上張望滔金。 院中可真熱鬧,春花似錦茂嗓、人聲如沸餐茵。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,755評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽钟病。三九已至,卻和暖如春刚梭,著一層夾襖步出監(jiān)牢的瞬間肠阱,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 31,987評論 1 266
  • 我被黑心中介騙來泰國打工朴读, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留屹徘,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 46,358評論 2 360
  • 正文 我出身青樓衅金,卻偏偏與公主長得像噪伊,于是被迫代替她去往敵國和親簿煌。 傳聞我的和親對象是個(gè)殘疾皇子,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,514評論 2 348

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