JVM 線上故障排查基本操作

# 前言

對(duì)于后端程序員淳梦,特別是 Java 程序員來(lái)講析砸,排查線上問(wèn)題是不可避免的。各種 CPU 飚高爆袍,內(nèi)存溢出首繁,頻繁 GC 等等,這些都是令人頭疼的問(wèn)題陨囊。樓主同樣也遇到過(guò)這些問(wèn)題弦疮,那么,遇到這些問(wèn)題該如何解決呢蜘醋?

首先胁塞,出現(xiàn)問(wèn)題,肯定要先定位問(wèn)題所在压语,然后分析問(wèn)題原因啸罢,再然后解決問(wèn)題,最后進(jìn)行總結(jié)胎食,防止下次再次出現(xiàn)扰才。

今天的文章,就如我們的題目一樣厕怜,講的是基本操作衩匣,也就是一些排查線上問(wèn)題的基本方法。為什么這么說(shuō)呢粥航?因?yàn)榫€上問(wèn)題千奇百怪琅捏,就算是身經(jīng)百戰(zhàn)的專(zhuān)家也會(huì)遇到棘手的問(wèn)題,因此不可能在一篇文章里說(shuō)完递雀,還有一個(gè)最重要的原因柄延,當(dāng)然就是樓主的水平不到位。

但不到位歸不到位映之,任何經(jīng)驗(yàn)都是值得記錄的拦焚,因此,樓主有必要將這些問(wèn)題記錄一下杠输。

還有赎败,本文的排查環(huán)境是 Linux.

#1. CPU 飚高

線上 CPU 飚高問(wèn)題大家應(yīng)該都遇到過(guò),那么如何定位問(wèn)題呢蠢甲?

思路:首先找到 CPU 飚高的那個(gè) Java 進(jìn)程僵刮,因?yàn)槟愕姆?wù)器會(huì)有多個(gè) JVM 進(jìn)程。然后找到那個(gè)進(jìn)程中的 “問(wèn)題線程”,最后根據(jù)線程堆棧信息找到問(wèn)題代碼搞糕。最后對(duì)代碼進(jìn)行排查勇吊。

如何操作呢?

  1. 通過(guò) top 命令找到 CPU 消耗最高的進(jìn)程窍仰,并記住進(jìn)程 ID汉规。
  2. 再次通過(guò) top -Hp [進(jìn)程 ID] 找到 CPU 消耗最高的線程 ID,并記住線程 ID.
  3. 通過(guò) JDK 提供的 jstack 工具 dump 線程堆棧信息到指定文件中驹吮。具體命令:jstack -l [進(jìn)程 ID] >jstack.log针史。
  4. 由于剛剛的線程 ID 是十進(jìn)制的,而堆棧信息中的線程 ID 是16進(jìn)制的碟狞,因此我們需要將10進(jìn)制的轉(zhuǎn)換成16進(jìn)制的啄枕,并用這個(gè)線程 ID 在堆棧中查找。使用 printf "%x\n" [十進(jìn)制數(shù)字] 族沃,可以將10進(jìn)制轉(zhuǎn)換成16進(jìn)制频祝。
  5. 通過(guò)剛剛轉(zhuǎn)換的16進(jìn)制數(shù)字從堆棧信息里找到對(duì)應(yīng)的線程堆棧。就可以從該堆棧中看出端倪脆淹。

從樓主的經(jīng)驗(yàn)來(lái)看常空,一般是某個(gè)業(yè)務(wù)死循環(huán)沒(méi)有出口,這種情況可以根據(jù)業(yè)務(wù)進(jìn)行修復(fù)未辆。還有 C2 編譯器執(zhí)行編譯時(shí)也會(huì)搶占 CPU窟绷,什么是 C2編譯器呢锯玛?當(dāng) Java 某一段代碼執(zhí)行次數(shù)超過(guò)10000次(默認(rèn))后咐柜,就會(huì)將該段代碼從解釋執(zhí)行改為編譯執(zhí)行,也就是編譯成機(jī)器碼以提高速度攘残。而這個(gè) C2編譯器就是做這個(gè)的拙友。如何解決呢?項(xiàng)目上線后歼郭,可以先通過(guò)壓測(cè)工具進(jìn)行預(yù)熱遗契,這樣,等用戶真正訪問(wèn)的時(shí)候病曾,C2編譯器就不會(huì)干擾應(yīng)用程序了牍蜂。如果是 GC 線程導(dǎo)致的,那么極有可能是 Full GC 泰涂,那么就要進(jìn)行 GC 的優(yōu)化鲫竞。

2. 內(nèi)存問(wèn)題排查

說(shuō)完了 CPU 的問(wèn)題排查,再說(shuō)說(shuō)內(nèi)存的排查逼蒙,通常从绘,內(nèi)存的問(wèn)題就是 GC 的問(wèn)題,因?yàn)?Java 的內(nèi)存由 GC 管理。有2種情況僵井,一種是內(nèi)存溢出了陕截,一種是內(nèi)存沒(méi)有溢出,但 GC 不健康批什。

內(nèi)存溢出的情況可以通過(guò)加上 -XX:+HeapDumpOnOutOfMemoryError 參數(shù)农曲,該參數(shù)作用是:在程序內(nèi)存溢出時(shí)輸出 dump 文件。

有了 dump 文件驻债,就可以通過(guò) dump 分析工具進(jìn)行分析了朋蔫,比如常用的MAT,Jprofile却汉,jvisualvm 等工具都可以分析驯妄,這些工具都能夠看出到底是哪里溢出,哪里創(chuàng)建了大量的對(duì)象等等信息合砂。

第二種情況就比較復(fù)雜了青扔。GC 的健康問(wèn)題。

通常一個(gè)健康的 GC 是什么狀態(tài)呢翩伪?根據(jù)樓主的經(jīng)驗(yàn)微猖,YGC 5秒一次左右,每次不超過(guò)50毫秒缘屹,F(xiàn)GC 最好沒(méi)有凛剥,CMS GC 一天一次左右。

而 GC 的優(yōu)化有2個(gè)維度轻姿,一是頻率犁珠,二是時(shí)長(zhǎng)。

我們看YGC互亮,首先看頻率犁享,如果 YGC 超過(guò)5秒一次,甚至更長(zhǎng)豹休,說(shuō)明系統(tǒng)內(nèi)存過(guò)大炊昆,應(yīng)該縮小容量,如果頻率很高威根,說(shuō)明 Eden 區(qū)過(guò)小凤巨,可以將 Eden 區(qū)增大,但整個(gè)新生代的容量應(yīng)該在堆的 30% - 40%之間洛搀,eden敢茁,from 和 to 的比例應(yīng)該在 8:1:1左右,這個(gè)比例可根據(jù)對(duì)象晉升的大小進(jìn)行調(diào)整姥卢。

如果 YGC 時(shí)間過(guò)長(zhǎng)呢卷要?YGC 有2個(gè)過(guò)程渣聚,一個(gè)是掃描,一個(gè)是復(fù)制僧叉,通常掃描速度很快奕枝,復(fù)制速度相比而言要慢一些,如果每次都有大量對(duì)象要復(fù)制瓶堕,就會(huì)將 STW 時(shí)間延長(zhǎng)隘道,還有一個(gè)情況就是 StringTable ,這個(gè)數(shù)據(jù)結(jié)構(gòu)中存儲(chǔ)著 String.intern 方法返回的常連池的引用郎笆,YGC 每次都會(huì)掃描這個(gè)數(shù)據(jù)結(jié)構(gòu)(HashTable)谭梗,如果這個(gè)數(shù)據(jù)結(jié)構(gòu)很大,且沒(méi)有經(jīng)過(guò) FGC宛蚓,那么也會(huì)拉長(zhǎng) STW 時(shí)長(zhǎng)激捏,還有一種情況就是操作系統(tǒng)的虛擬內(nèi)存,當(dāng) GC 時(shí)正巧操作系統(tǒng)正在交換內(nèi)存凄吏,也會(huì)拉長(zhǎng) STW 時(shí)長(zhǎng)远舅。

再來(lái)看看FGC,實(shí)際上痕钢,F(xiàn)GC 我們只能優(yōu)化頻率图柏,無(wú)法優(yōu)化時(shí)長(zhǎng),因?yàn)檫@個(gè)時(shí)長(zhǎng)無(wú)法控制任连。如何優(yōu)化頻率呢蚤吹?

首先,F(xiàn)GC 的原因有幾個(gè)随抠,1 是 Old 區(qū)內(nèi)存不夠裁着,2 是元數(shù)據(jù)區(qū)內(nèi)存不夠,3 是 System.gc()暮刃, 4 是 jmap 或者 jcmd跨算,5 是CMS Promotion failed 或者 concurrent mode failure,6 JVM 基于悲觀策略認(rèn)為這次 YGC 后 Old 區(qū)無(wú)法容納晉升的對(duì)象椭懊,因此取消 YGC,提前 FGC步势。

通常優(yōu)化的點(diǎn)是 Old 區(qū)內(nèi)存不夠?qū)е?FGC氧猬。如果 FGC 后還有大量對(duì)象,說(shuō)明 Old 區(qū)過(guò)小坏瘩,應(yīng)該擴(kuò)大 Old 區(qū)盅抚,如果 FGC 后效果很好,說(shuō)明 Old 區(qū)存在了大量短命的對(duì)象倔矾,優(yōu)化的點(diǎn)應(yīng)該是讓這些對(duì)象在新生代就被 YGC 掉妄均,通常的做法是增大新生代柱锹,如果有大而短命的對(duì)象,通過(guò)參數(shù)設(shè)置對(duì)象的大小丰包,不要讓這些對(duì)象進(jìn)入 Old 區(qū)禁熏,還需要檢查晉升年齡是否過(guò)小。如果 YGC 后邑彪,有大量對(duì)象因?yàn)闊o(wú)法進(jìn)入 Survivor 區(qū)從而提前晉升瞧毙,這時(shí)應(yīng)該增大 Survivor 區(qū),但不宜太大寄症。

上面說(shuō)的都是優(yōu)化的思路宙彪,我們也需要一些工具知道 GC 的狀況。

JDK 提供了很多的工具有巧,比如 jmap 释漆,jcmd 等,oracle 官方推薦使用 jcmd 代替 jmap篮迎,因?yàn)?jcmd 確實(shí)能代替 jmap 很多功能灵汪。jmap 可以打印對(duì)象的分布信息,可以 dump 文件柑潦,注意享言,jmap 和 jcmd dump 文件的時(shí)候會(huì)觸發(fā) FGC ,使用的時(shí)候注意場(chǎng)景渗鬼。

還有一個(gè)比較常用的工具是 jstat览露,該工具可以查看GC 的詳細(xì)信息,比如eden 譬胎,from差牛,to,old 等區(qū)域的內(nèi)存使用情況堰乔。

還有一個(gè)工具是 jinfo偏化,該工具可以查看當(dāng)前 jvm 使用了哪些參數(shù),并且也可以在不停機(jī)的情況下修改參數(shù)镐侯。

包括我們上面說(shuō)的一些分析 dump 文件的可視化工具侦讨,MAT抚笔,Jprofile任洞,jvisualvm 等,這些工具可以分析 jmap dump 下來(lái)的文件着撩,看看哪個(gè)對(duì)象使用的內(nèi)存較多崇猫,通常是能夠查出問(wèn)題的沈条。

還有很重要的一點(diǎn)就是,線上環(huán)境一定要帶上 GC 日志W缏@酢屋厘!

總結(jié)

基于文章的標(biāo)題,我們這個(gè)是基本操作月而,故障排查是說(shuō)不完的話題汗洒,每個(gè)故障涉及的知識(shí)也都很多,因此景鼠,我們?cè)趯W(xué)習(xí)了基本的排查之后仲翎,還需要學(xué)習(xí)更多事故排查技術(shù),比如排查 IO铛漓,網(wǎng)絡(luò)溯香,TCP 連接等等。樓主將在后面的文章中將這些基本操作都記錄下來(lái)浓恶。

good luckC堤场!0湿镀!

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市伐憾,隨后出現(xiàn)的幾起案子勉痴,更是在濱河造成了極大的恐慌,老刑警劉巖树肃,帶你破解...
    沈念sama閱讀 210,914評(píng)論 6 490
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蒸矛,死亡現(xiàn)場(chǎng)離奇詭異,居然都是意外死亡胸嘴,警方通過(guò)查閱死者的電腦和手機(jī)雏掠,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 89,935評(píng)論 2 383
  • 文/潘曉璐 我一進(jìn)店門(mén),熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái)劣像,“玉大人乡话,你說(shuō)我怎么就攤上這事《龋” “怎么了绑青?”我有些...
    開(kāi)封第一講書(shū)人閱讀 156,531評(píng)論 0 345
  • 文/不壞的土叔 我叫張陵,是天一觀的道長(zhǎng)吮铭。 經(jīng)常有香客問(wèn)我时迫,道長(zhǎng),這世上最難降的妖魔是什么谓晌? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 56,309評(píng)論 1 282
  • 正文 為了忘掉前任,我火速辦了婚禮癞揉,結(jié)果婚禮上纸肉,老公的妹妹穿的比我還像新娘溺欧。我一直安慰自己,他們只是感情好柏肪,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,381評(píng)論 5 384
  • 文/花漫 我一把揭開(kāi)白布姐刁。 她就那樣靜靜地躺著,像睡著了一般烦味。 火紅的嫁衣襯著肌膚如雪聂使。 梳的紋絲不亂的頭發(fā)上,一...
    開(kāi)封第一講書(shū)人閱讀 49,730評(píng)論 1 289
  • 那天谬俄,我揣著相機(jī)與錄音柏靶,去河邊找鬼。 笑死溃论,一個(gè)胖子當(dāng)著我的面吹牛屎蜓,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播钥勋,決...
    沈念sama閱讀 38,882評(píng)論 3 404
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼炬转,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼!你這毒婦竟也來(lái)了算灸?” 一聲冷哼從身側(cè)響起扼劈,我...
    開(kāi)封第一講書(shū)人閱讀 37,643評(píng)論 0 266
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤,失蹤者是張志新(化名)和其女友劉穎菲驴,沒(méi)想到半個(gè)月后荐吵,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體,經(jīng)...
    沈念sama閱讀 44,095評(píng)論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡谢翎,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,448評(píng)論 2 325
  • 正文 我和宋清朗相戀三年捍靠,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片森逮。...
    茶點(diǎn)故事閱讀 38,566評(píng)論 1 339
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡榨婆,死狀恐怖,靈堂內(nèi)的尸體忽然破棺而出褒侧,到底是詐尸還是另有隱情良风,我是刑警寧澤,帶...
    沈念sama閱讀 34,253評(píng)論 4 328
  • 正文 年R本政府宣布闷供,位于F島的核電站烟央,受9級(jí)特大地震影響,放射性物質(zhì)發(fā)生泄漏歪脏。R本人自食惡果不足惜疑俭,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,829評(píng)論 3 312
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望婿失。 院中可真熱鬧钞艇,春花似錦啄寡、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 30,715評(píng)論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至飘弧,卻和暖如春识藤,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背次伶。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 31,945評(píng)論 1 264
  • 我被黑心中介騙來(lái)泰國(guó)打工痴昧, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留,地道東北人学少。 一個(gè)月前我還...
    沈念sama閱讀 46,248評(píng)論 2 360
  • 正文 我出身青樓剪个,卻偏偏與公主長(zhǎng)得像,于是被迫代替她去往敵國(guó)和親版确。 傳聞我的和親對(duì)象是個(gè)殘疾皇子扣囊,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,440評(píng)論 2 348

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