線上OOM:GC Overhead Limit Exceeded異常排查(一)

一、背景

上週五,其他項目組違背了週五不能發版的規定,18:30下班前兩個系統發了新版

19:30運營反饋系統很卡,華爲雲CPU100%報警

二、解決思路

因爲應用服務器不同項目組是共用的,影響到我負責的系統,所以我也幫忙排查

第一直覺判斷應該是內存泄露或大對象

因爲數組內存分配在Oracle JDK8空間必須是連續的(IBM J9不是),如果大對象無法申請到足夠的內存,那麼就會OOM

檢查週五提交的代碼記錄,發現select *where條件名字數據在20W,並且使用Stream.collect產生新集合,局部變量一直持有原集合,預估數據量在40W左右,並且接口屬於數據同步類型的,基本上每2分鐘一次拉取,因爲大數據查詢耗時,算上併發時客戶端數量在20個左右,峯值數量在800W,這僅僅是其中一個數據同步接口,如果應用服務器其他接口內存申請觸發GC,處理延遲,峯值更高,由於都存在引用,full gc也無法回收內存,故JVM拋出OOM

先回滾了代碼,定位問題大概用了20-30分鐘

三、思考

拋開代碼code review和開發的問題,談談大對象的優化

通常大對象發生的場景

  1. 數據導入導出
  2. 文件服務器
  3. 批處理任務 ......

優化的方法

  1. 可以每次取小量,使用offset記錄偏移量,在循環中處理
  2. 在使用完後的數據,後續不用時,對局部變量賦值爲null,這種在處理耗時較長場景提升較大
  3. 儘量不要查出數據在應用中聚合統計
  4. 流處理(mybatis支持流和遊標返回數據)

原理就是尋找大數據小內存的通用解

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