StringBuilder引起的OOM[線上]

背景

最近一個大版本上線,上線前做了codereview,發佈時也只發了一臺機器,放量10%,結果這一臺機器到了晚上10點時,eureka狀態被置爲outofservice;當時沒有同視這一情況,加上各種產品催,冒着風險全量發佈了,晚上6點左右被叫去分析問題,晚上8點左右服務器出現內存異常升高,機器上的應用直接被系統kill掉,晚上9:21服務不可用,工單狂漲,然後回滾,20分鐘後恢復服務。
服務高峯期是晚上6:30到8:30,這是典型的死在了下坡上。從這種現象分析,泄漏點不是核心流程。

分析

第二天重啓組織代碼分析,dump文件(出事前把流量切斷dump出來的)分析。

一、通過jProfiler分析

在這裏插入圖片描述
堆內存使用僅283M,線程倒是很多,然後啥也沒能分析出來
在這裏插入圖片描述
在這裏插入圖片描述

二、通過MAT分析

使用MAT查看內存使用的餅圖,跟jprofiler的情況是差不多的。
在這裏插入圖片描述
點南[Dominator Tree] 去查看大對象
在這裏插入圖片描述
這樣看也是啥也看不出來,那麼分析一下,上一個版本的代碼沒出問題,這個版本的代碼了出現這種情況,那肯定是這之間改動有關,查找這期間改動的類,進行分析。

在頂部Class Name下面的查詢輸入框中輸入包名或類名進行查找,結果發佈
在這裏插入圖片描述

把StringBuilder做爲成員變量了!!!!!
分析相關代碼,終於找到真相,在方法中,調用了StringBuilder#append(String)方法, 而且這幾個方法都是用戶在覈心流程完成之後,會調用的接口執行,所以這也解釋了爲啥會死在下坡上。

總結

1、在上線後發現問題,並且沒有找到原因的情況下,嚴禁全量發佈。
2、使用一些靜態掃描工具分析代碼,添加會引起故障的掃描規範在上線前掃代碼。
3、出現問題,要眼觀全局,當事情無法快速定位、快速恢復的情況下,及時回滾。
4、對線上一定要有敬畏之心!!!!敬畏之心!!!!敬畏之心!!!!

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章