一次真實的線上 OOM 問題定位
概述
近日,負責的一系統生產環境上出現了OutOfMemoryError,伴隨著這個問題隨之而來的是一堆Full GC, CPU 百分之百,頻繁宕機重啟等問題,嚴重影響業務的推廣及使用,此類問題一般處理起來比較棘手,本文將此問題的出現及定位解決過程做下梳理,以便對後續處理類似問題提供參考指導。 注:該問題前面發了一版,因有些描述不太恰當,後來刪除了,少數先得者看到了,想再看下發現已被刪除,私信諮詢我怎麼找不到了,由此可見,很多同事還是比較在意此類問題的,很好,重新梳理下,補上一篇。
問題出現
軟體:WildFly standalone 8.1.0.Final(OpenJDK) 報警內容:日誌中有OutOfMemoryError資訊 環境:PRD 報警級別:嚴重 報警時間:2019-04-09 11:04:59 當前時間:2019-04-09 11:06:03 監控項名稱:jboss日誌OutOfMemoryError 最新資料:2019-04-09 11:03:38,791 ERROR [stderr] (RMI RenewClean-[net.sf.ehcache.distribution.ConfigurableRMIClientSocketFactory@1d4c0]) Exception in thread "RMI RenewClean-[net.sf.ehcache.distribution.ConfigurableRMIClientSocketFactory@1d4c0]" java.lang.OutOfMemoryError: Java heap space
第一步: 重啟服務
做好機器隔離,重啟服務,保證不影響業務使用!
第二步: 收集dump檔案
第三步: 利用JVM故障處理工具分析問題
開啟jvisualvm工具
載入dump檔案
查詢保留大小最大的物件
重點關注前幾位
檢視例項數最大的例項
分析可能的原因
從例項上看JDBC42ResultSet佔用空間最大,從而大膽猜測與查詢相關,那麼就看詳情中能否找到是哪個sql導致的問題, 檢視owningstatemeng語句集:
檢視原始sql: originalSql
sql詳情:
納尼,where 1=1?相當於沒帶條件查所有記錄,那麼,表中有多少記錄呢,不多,也就20萬不到吧
至此,改問題的原因似乎顯而易見。
第四步:緊急釋出
於當晚拉緊急版本,通宵釋出處理,以免問題重現。
總結
此問題是由於研發人員疏漏,查詢字典表資料未帶查詢條件,導致查出表中所有記錄進行ORM處理導致記憶體溢位。定位過程看似簡單,但如何能在第一時間迅速排查原因並給出解決方案,難度還是不小的,由於缺乏經驗,往往不知該怎麼入手,況且線上異常場景複雜多變,不保證這個地方優化了,後續就沒有問題了,需要在 現網環境經住考驗 才行。
事實證明,此問題優化後,現網仍然有較多其他問題待解決,目前正在組織專家會診,待後續有時間再做總結吧。