Excel生成之java heap space異常

Excel生成之java heap space異常

問題場景

在使用poi操作,生成一個6w行,45列的excel的時候,老是報內存不夠用(java heap space異常)。
一開始以爲是默認啓動時,內存太小,就把堆內存調至2G,但是依然報內存不夠用
後來想,一個這個excel,大小最多就10m左右,數據量也不大,不應該佔用這麼多內存。
因此,用jvm工具,看了下內存情況

excel代碼示例如下:
使用的是XSSFWorkbook,去生成excel

XSSFWorkbook xwb = new XSSFWorkbook(ins);
XSSFSheet sheet = xwb.getSheetAt(0);
XSSFRow row = sheet.createRow(1);
XSSFCell cell = row.createCell(1);

分析過程

爲了分析內存佔用情況,使用jvisualvm,對啓動的進程做監控分析

1.內存佔用和CPU情況

jvm監控截圖
說明:在開始生成excel的時候,可以看到內存大幅度的增長,然後jvm對內存進行了擴容,但是依然在持續性上漲,通過cpu的活動情況,也能看到後續一直在頻繁GC,但是GC後,清理不了多少內存,證明很多對象創建了,被引用了,垃圾回收器做不了回收操作
此時:初步定位,java heap space異常,應該和poi操作有關係

2.內存對象分析

在這裏插入圖片描述
說明:通過“抽樣器”,對內存進行抽象分析。發現,Xobj.ElementXobj、Xobj.AttrXobj對象
有800w+個實例,下方還有部分對象,也存在大量實例。通過網上查閱資料,發現,poi操作,有兩種模式,XSSFWorkbook模式 和 SXSSFWorkbook模式。第一種模式,就是現在使用對方式,此方式僅適用與小數據量的poi操作;第二種SXSSFWorkbook,適用與較大數據量的poi操作,看了下。

3.問題定位

通過對jvm的內存分析,定位到是XSSFWorkbook的使用,導致的內存爆炸了。

解決方案

代碼如下:
說明:將 XSSFWorkbook包裝一下,生成SXSSFWorkbook對象,後續poi操作均使用
Sheet、Row、Cell等接口。問題解決

XSSFWorkbook xwb = new XSSFWorkbook(ins);
SXSSFWorkbook workbook = new SXSSFWorkbook(xwb);
Sheet sheet = workbook.getSheetAt(0);

效果

在這裏插入圖片描述
在這裏插入圖片描述

內存基本平穩,GC能對對象做有效得回收,堆內存中的對象也無上述問題中,那麼多額外的內存開銷的對象佔用了。

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