情景:周五的時(shí)候辖所,運(yùn)維突然發(fā)現(xiàn)平時(shí)正常運(yùn)行的服務(wù)重啟了擅笔,同時(shí)查看了日志,發(fā)現(xiàn)有g(shù)c outOfMemory的日志汹押,并且生成了當(dāng)時(shí)的dump文件矿筝,通知我有時(shí)間的話(huà)排查下問(wèn)題,是什么導(dǎo)致重啟的棚贾,平時(shí)都沒(méi)有這種情況窖维;
剛好這周事情少,有點(diǎn)時(shí)間妙痹,就開(kāi)始著手排查陈辱;
1.準(zhǔn)備mat軟件
首先從網(wǎng)上下載下mat軟件,我這里用的是mac OS版本的细诸,安裝完后沛贪,用命令行打開(kāi),具體方式可以自行百度震贵,同時(shí)從ftp上下載log文件以及dump文件
mac OS mat.app 下載鏈接:
鏈接: https://pan.baidu.com/s/1nMa_XqK_DPtd6GPz5PioOg 密碼: 7aur
可以通過(guò)上面的file->open file利赋,選擇自己的dump文件路徑,注意dump文件的格式是有要求的,否則打不開(kāi)猩系,我這里用的都是*.bin結(jié)尾的媚送;
2.使用Leak Suspects Report初步分析
打開(kāi)文件,后會(huì)跳出下面彈窗
選擇Leak Suspects Report然后點(diǎn)擊finish寇甸,等待軟件一段時(shí)間的解析后會(huì)出現(xiàn)以下界面:
咱們著重看自己相關(guān)的類(lèi)塘偎,翻到最下面可以看到e,也就是Problem Suspect5,點(diǎn)擊Details拿霉,出現(xiàn)以下界面
由上面圖片可以看到是ibatis相關(guān)操作導(dǎo)致的吟秩,百度查詢(xún)下class org.apache.ibatis.executor.result.DefaultResultHandler導(dǎo)致的相關(guān)問(wèn)題,發(fā)現(xiàn)它的作用是將statement執(zhí)行后的結(jié)果绽淘,轉(zhuǎn)換成對(duì)象列表涵防;
3.分析該對(duì)象是否存在強(qiáng)引用
如圖:點(diǎn)擊查看其GC ROOT對(duì)象是由tomcat引用,由此可知沪铭,肯定是某一個(gè)接口導(dǎo)致查詢(xún)數(shù)據(jù)庫(kù)的數(shù)據(jù)量過(guò)大壮池,然后最終導(dǎo)致outOfMemory;
4.定位到最終問(wèn)題杀怠,即是哪條sql導(dǎo)致
在當(dāng)前頁(yè)面點(diǎn)擊按鈕
出現(xiàn)以下界面
這是根據(jù)Retained Heap 進(jìn)行從大到小排序后的結(jié)果椰憋;
從大到小,逐個(gè)打開(kāi)其中的內(nèi)容赔退,將里面的sql內(nèi)容復(fù)制出來(lái)橙依,然后去線(xiàn)上數(shù)據(jù)倉(cāng)庫(kù),進(jìn)行count查詢(xún),查看具體返回條數(shù)票编,這里我看到http-nio-8018-exec-2 線(xiàn)程中的sql執(zhí)行,查詢(xún)到了14W條數(shù)據(jù)卵渴,定位到是這條sql引起的outOfMemory慧域;
5.定位具體代碼
有了sql就好辦了,在項(xiàng)目中查詢(xún)到相關(guān)sql浪读,以及引用之處昔榴,發(fā)現(xiàn)一共有三個(gè)接口使用了,該方法碘橘,根據(jù)報(bào)錯(cuò)時(shí)間范圍和接口名去kibina中查詢(xún)相關(guān)接口的請(qǐng)求入?yún)⒒ザl(fā)現(xiàn)就是其中一個(gè)接口的入餐沒(méi)有傳入所需參數(shù),導(dǎo)致查詢(xún)出14W條數(shù)據(jù)痘拆,最終產(chǎn)生了outOfMemory仰禽;
具體解決方案的話(huà)就視業(yè)務(wù)而定了,最簡(jiǎn)單的方案就是如果該參數(shù)為空則返回參數(shù)異常纺蛆;