一赁炎、背景介紹
公司對外提供了一個API系統(tǒng),提供了產(chǎn)品的搜索钾腺,查詢徙垫,價(jià)格以及訂單相關(guān)等功能,由我來負(fù)責(zé)開發(fā)維護(hù)放棒。這個系統(tǒng)部署在一個獨(dú)立的 JBoss 實(shí)例里姻报。大概從2018年2月以來,該系統(tǒng)不定時 down 機(jī)间螟。因?yàn)橥粋€服務(wù)器上還跑了另外兩個Jboss吴旋,一開始還以為是服務(wù)器物理內(nèi)存不夠,API系統(tǒng)掛了之后厢破,只是簡單地重啟了一下相關(guān)的Jboss荣瑟。最近將其中的一個Jboss遷移到別的服務(wù)器了,但是API系統(tǒng)還是會不定時地掛掉摩泪,于是特地安排了時間來跟蹤一下這個問題笆焰。
二、前期準(zhǔn)備
首先打開GC日志见坑,在Jboss的 bin目錄里面的 standalone.conf 文件里面的 JAVA_OPTS 行里面嚷掠,加上這兩個選項(xiàng): ?“-verbose.gc ?-Xloggc:/server/gc.log”;
接著鳄梅,打開OOM 時記錄 HeapDump的選項(xiàng)叠国。在 standalone.conf 文件里面的 JAVA_OPTS 行里面戴尸,加上這個選項(xiàng) ?“-XX:+HeapDumpOnOutOfMemoryError”孙蒙;
最后挎峦,重新啟動 jboss坦胶。等待下一次API系統(tǒng) down 機(jī)。
幸運(yùn)地(也可以說不幸)峭咒,重啟之后第三天纪岁,API系統(tǒng)又掛了幔翰。從服務(wù)器取回GC日志(/server/gc.log)遗增,還有內(nèi)存溢出HeapDump文件(java_pid14584.hprof, 在 bin 目錄下霍狰,文件名可能不是這個蚓耽,但是類似于這個)步悠。
三鼎兽、分析
1.?分析GC活動
使用?gcviewer?打開下載回來的?gc.log谚咬,發(fā)現(xiàn)GC方面沒有什么問題择卦,內(nèi)存占用挺正常的秉继。到最后down機(jī)前尚辑,都沒有發(fā)現(xiàn)GC異常杠茬。
2. 分析 HeapDump 文件
使用 Eclipse 的 MAT 工具打開下載回來的 ?java_pid14584.hprof 文件瓢喉,然后等待MAT分析完成灯荧。
打開 Leak Suspects哆窿,看看有哪些可疑的線程:
嗯挚躯?http-executor-threads 這個線程占用了 800多M的內(nèi)存码荔?點(diǎn) “See stacktrace” 去看看它的調(diào)用棧缩搅。
CommonDateUtil的getBetweenDates() 方法導(dǎo)致了異常硼瓣?先看看這個方法是干啥的
大略看了一下堂鲤,參數(shù)合理的話瘟栖,應(yīng)該沒有什么問題啊半哟。
再去看看內(nèi)存占用镜沽,這個占用了 800多M內(nèi)存的線程贱田,到底都存了些什么男摧?回到 Overview耗拓,點(diǎn)擊 “Histogram”乔询,看看各類占用的內(nèi)存
咦竿刁?怎么有個 ArrayList 占用了 800多M 的內(nèi)存食拜?右擊這一行负甸,選擇 ?“l(fā)ist objects” ? → ?“with outgoing references”呻待,看看這個 ArrayList 里面到底存了些什么蚕捉?
到了這個頁面报破,點(diǎn)擊展開那個 800多M的 ArrayList的 elementData充易。看看具體元素的內(nèi)容。因?yàn)樵?ArrayList 的內(nèi)容較多,展開的時間會比較長(我的I7-4800MQ /12G內(nèi)存控漠,也花了2分鐘)盐捷。
怎么都是日期類的字符串?這不是那個CommonDateUtil的getBetweenDates() 產(chǎn)生的日期字符串嗎?怎么加到了 2069-11-19? 死循環(huán)了嗎习霹?
三、解決辦法
1.?簡單解決
既然問題出在CommonDateUtil的getBetweenDates()?方法里爸吮,再加上一層限制,防止死循環(huán)就行了桐早。例如:只返回最多一年的日期字符串哄酝。
2.?根本解決
在API接口層次作限制,每次只能小批量返回一部分的價(jià)格搀军,例如說?31?天焚刺。
四、文中用到的工具
1. GcViewer
圖形化查看?JVM GC活動的工具匾委。1.33及之前版本可以使用JDK1.7運(yùn)行,1.34開始需要使用JDK1.8運(yùn)行。下載地址:?http://sourceforge.net/projects/gcviewer/
2. Eclipse Memory Analyzer (MAT)
多維度分析?HeapDump?文件的工具。由于?HeapDump?文件比較大,建議下載64位的版本來使用乳幸。下載地址:http://www.eclipse.org/mat/downloads.php