1. 程式人生 > >一次線上記憶體洩漏的問題排查

一次線上記憶體洩漏的問題排查

上線了好久的專案今天突然出現cpu到達100% 的情況,先將專案緊急重啟,恢復正常後登入伺服器排查gc日誌,發現存在記憶體洩漏的情況。

top命令檢視程序情況,top -Hp pid檢視執行緒,再jstack匯出日誌。過程匆忙,忘了截圖

搜尋jsatck日誌看到許多執行緒阻塞在這一行程式碼

基本可以定位到問題,是由於CertUtil中的建立的某些物件一直沒有被回收導致的。而CertUtil並不是靜態的,而是每次請求建立一個,因此當併發量提升時,新建立的物件會佔滿記憶體。

檢視日誌系統,發現果然近兩天的請求數量劇增

 


在mat中匯入dump檔案分析,可以看到與jstack日誌中結論一致,JcsSecurity類中的map維護了大量的org.bouncycastle.jce.provider.BouncyCastleProvider物件,這些物件一直沒有被釋放,直到佔滿了記憶體空間

 

JcsSecurity類原始碼顯示其內部維護一個靜態的map--verificationResults,它在呼叫鏈中只存在put操作,不存在remove操作,因此每次呼叫後在map中維護的value無法被回收。由此我們可以知道,該類的設計初衷,應當是讓我們單例或靜態呼叫,不應當持續建立新物件

 

第一次排查OOM,其實過程遠沒有部落格描述的這般順利。此次事故之後,相信以後的記憶體問題排查會更加得心應手。