(點選上方公眾號,可快速關註)
來源:木杉的部落格 ,
imushan.com/2018/05/28/java/debug/JVM堆記憶體使用率持續上升的一種排查思路/
最近新版本釋出後,在執行一段時間後程式突然無響應了,觀察監控,發現JVM堆記憶體佔用在某個時間點突然飆升,最終導致應用無響應:
重啟Tomcat後,應用恢復正常,並且後續時間沒有發生記憶體上漲問題。
分析這個JVM記憶體曲線,他是直線上升的,以前遇到過類似的場景,會導致這種直線(勻速)上升的,一般是一個死迴圈導致的,如果是普通請求資源洩露的話,上升曲線不會這麼平穩,會和請求量有一定的關係。
死迴圈導致這個執行緒的資源無法釋放,隨著迴圈次數的增多,累積的物件越來越多,最終導致堆記憶體耗盡。
那要如何定位到具體的死迴圈位置呢?這個是個難題。之前遇到類似的問題是透過dump生產環境的JVM記憶體來分析,耗時耗力。結合之前的經驗,這次我直接去nginx日誌搜尋響應碼為504的請求,果不其然,在記憶體飆升時間點附近,有一個被響應504的請求。
504是什麼響應碼呢?這個響應碼比較少遇到,指的是閘道器超時 (Gateway timeout)。當一個請求到Tomcat後,Tomcat如果陷入死迴圈,那麼這個請求自然無法得到響應,nginx等待響應超時,響應給使用者504。
504響應時間點和記憶體飆升時間點對的上,那麼大機率就是這個介面導致的,詳細分析這個介面的程式碼,發現了在特殊引數的情況下,會進入死迴圈,修改後問題解決。
總結:
-
觀察JVM記憶體曲線,是否是勻速上升
-
搜尋Nginx響應碼為504的日誌,檢視日誌時間是否和記憶體上升時間點匹配
-
分析Nginx響應碼為504的請求,確認是否存在死迴圈邏輯
看完本文有收穫?請轉發分享給更多人
關註「ImportNew」,提升Java技能