JVM CPU高問(wèn)題排查

好好地碼代碼呢,突然接到線上的告警,說(shuō)是CPU飆高。然后就稀里嘩啦的連上線上的服務(wù)器,使用top命令查看了一下CPU情況,發(fā)現(xiàn)我們的服務(wù)CPU占到600%。然后就開(kāi)始定位CPU占用高的線程。主要有以下幾步:

查詢出問(wèn)題的服務(wù)進(jìn)程id  : ps -ef | grep mrf-center | grep -v grep
查詢?cè)撨M(jìn)程內(nèi)最耗費(fèi)CPU的線程  top -Hp pid
轉(zhuǎn)換線程id為16進(jìn)制  printf "%x\n" 21742
查找特定線程的信息  jstack 21711 | grep 54ee

具體的定位過(guò)程可以參考大神你假笨的文章如何定位消耗CPU最多的線程
最后定位出這樣一個(gè)線程

好了,問(wèn)題來(lái)了,CPU占用過(guò)高不是因?yàn)闃I(yè)務(wù)代碼中有CPU密集型任務(wù)或者是死循環(huán)造成的,而是因?yàn)镚C太頻繁導(dǎo)致的。好,那就驗(yàn)證一下吧。

那gc情況來(lái)看可以看出以下幾個(gè)問(wèn)題

  • 老年代和年輕代快占滿了
  • 頻繁Full GC,但是回收效果不好
  • 兩個(gè)Survivor區(qū)有時(shí)候都是空的

由此可以猜想頻繁Full GC是因?yàn)槔夏甏煺紳M了,而老年代慢了不是因?yàn)閑den區(qū)中的對(duì)象因?yàn)槟挲g到了可以晉升為老年代的年齡,而是因?yàn)镋den區(qū)中有大對(duì)象,導(dǎo)致在進(jìn)行minor gc后,無(wú)法回收的對(duì)象過(guò)大導(dǎo)致沒(méi)法放進(jìn)Survivor區(qū),從而只能放進(jìn)老年代。

所以用一句總結(jié)就是,大對(duì)象很可怕,朝生夕死的大對(duì)象更可怕

那接下來(lái)就需要驗(yàn)證自己的猜想,使用jmap命令來(lái)dump出jvm的內(nèi)存

jmap -dump:format=b,file=mm2.dump pid

注意,jmap命令會(huì)導(dǎo)致jvm停滯,線上慎用。

下面就是使用工具來(lái)分析一下堆內(nèi)存文件了,推薦使用MAT工具(eclipse 插件)。不過(guò)我不太推薦在eclipse中安裝這個(gè)插件,因?yàn)樵诜治龆褍?nèi)存的時(shí)候比較耗費(fèi)內(nèi)存,而eclipse又是比較耗費(fèi)內(nèi)存的,所以我推薦使用stand-alone的mat工具,可以在此下載

但是,不幸的是你可能打不開(kāi)這個(gè)工具,并且報(bào)下面這個(gè)錯(cuò)誤

Java was started but returned exit code=13 

這個(gè)問(wèn)題可以參照下面這個(gè)來(lái)解決Java was started but returned exit code=13

還有就是,一般堆內(nèi)存文件都比較大,比較耗費(fèi)內(nèi)存。所以為了加載得比較快的話,可以調(diào)整一下文件
MemoryAnalyzer.ini中的最大堆內(nèi)存 。比如我就調(diào)整為2G了。-Xmx2048m

好了,完事具備,只欠分析堆內(nèi)存了。
查看histogram圖,然后按照retained heap 排序,可以看到這個(gè)PageData占用了將近600M的內(nèi)存。

為什么就看PageData類(lèi)型的對(duì)象呢,因?yàn)檫@個(gè)對(duì)象是我們系統(tǒng)中定義的對(duì)象,所以優(yōu)先看

再看一下支配樹(shù)


好了,發(fā)現(xiàn)是因?yàn)镻ageData中的List中裝了非常多的HashMap對(duì)象。由此可見(jiàn)是因?yàn)閺臄?shù)據(jù)庫(kù)中查詢了過(guò)多的對(duì)象導(dǎo)致的。

這樣就大概知道了是因?yàn)榇a中有一個(gè)不合理的查詢。下面即使定位是哪一個(gè)查詢了。

其實(shí)在看到支配樹(shù)的數(shù)據(jù)的時(shí)候也大概能知道是哪一個(gè)表中的數(shù)據(jù)了,再結(jié)合一下查詢就大概知道了。

不過(guò)我是從線程棧中看到的(可以通過(guò)使用jstack命令來(lái)dump出線程棧)

好了,至此就定位出問(wèn)題了。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
【社區(qū)內(nèi)容提示】社區(qū)部分內(nèi)容疑似由AI輔助生成,瀏覽時(shí)請(qǐng)結(jié)合常識(shí)與多方信息審慎甄別。
平臺(tái)聲明:文章內(nèi)容(如有圖片或視頻亦包括在內(nèi))由作者上傳并發(fā)布,文章內(nèi)容僅代表作者本人觀點(diǎn),簡(jiǎn)書(shū)系信息發(fā)布平臺(tái),僅提供信息存儲(chǔ)服務(wù)。

相關(guān)閱讀更多精彩內(nèi)容

  • 從三月份找實(shí)習(xí)到現(xiàn)在,面了一些公司,掛了不少,但最終還是拿到小米、百度、阿里、京東、新浪、CVTE、樂(lè)視家的研發(fā)崗...
    時(shí)芥藍(lán)閱讀 42,767評(píng)論 11 349
  • 這篇文章是我之前翻閱了不少的書(shū)籍以及從網(wǎng)絡(luò)上收集的一些資料的整理,因此不免有一些不準(zhǔn)確的地方,同時(shí)不同JDK版本的...
    高廣超閱讀 16,040評(píng)論 3 83
  • http://www.cnblogs.com/angeldevil/p/3801189.html值得一看 Clas...
    snail_knight閱讀 1,610評(píng)論 1 0
  • Java 應(yīng)用性能優(yōu)化是一個(gè)老生常談的話題,典型的性能問(wèn)題如頁(yè)面響應(yīng)慢、接口超時(shí),服務(wù)器負(fù)載高、并發(fā)數(shù)低,數(shù)據(jù)庫(kù)頻...
    Rick617閱讀 7,599評(píng)論 1 9
  • JVM架構(gòu) 當(dāng)一個(gè)程序啟動(dòng)之前,它的class會(huì)被類(lèi)裝載器裝入方法區(qū)(Permanent區(qū)),執(zhí)行引擎讀取方法區(qū)的...
    cocohaifang閱讀 1,825評(píng)論 0 7

友情鏈接更多精彩內(nèi)容