poi導致內存泄露分析
背景
最近線上的機器偶爾會出現cpu打滿的情況,內存也很吃緊,導致影響系統的正常運行。如下:
可以看出,已經嚴重影響到線上程序的運行了。
分析
用jmap打出對應的dump文件並用MAT工具打開。
很明顯發生了內存泄露。
觀察一下支配樹。
可以看出,佔用內存最多的是char[]數組對象,總共有700+萬個。其次是XSSFSheet,共應用了300+mb的對象。
我們再看看當時的線程棧是怎樣的。
頻繁出現poi的相關類很明顯有問題。
查看代碼,這是解析上傳的excel相關的代碼。
是不是上上傳的excel大小太大了呢?
看一看出poi內部是用treemap存儲列和行信息的。
我們分別打印一下行數和列數
發現這是一個有234行和16384列組成的excel,按照預期,我們要求上傳的excel只需要有一列就可以了。除此之外,表面上看excel也不是很大啊。
我們嘗試創建一個這樣的excel,並上傳。
問題復現了
我們來看看excel有多大,只有15mb,15mb卻用了2Gb左右的內存來解析,經過排查,排除了代碼的問題。那麼可能出錯的就只有poi本身了。
經過調查,poi分爲用戶模式和sax模式來解析excel,用戶模式適合處理小數據量的excel,sax適合用來存儲數據量的excel,而項目中用的是用戶模式,改變爲sax模式或者限制上傳的excel大小即可解決。
具體poi的相關知識這裏不再細說。