在這段代碼中,我使用 Apache POI 庫加載了一個大小為 10MB 的 Excel 文件。這消耗了近 2GB 的內(nèi)存。遍歷所有行后,我終于調(diào)用了 close 方法。但是,GC 似乎沒有釋放此流和對象消耗的空間。并且仍然使用 2GB + 400MB 的內(nèi)存。有任何想法嗎?這是我的代碼:public List<Meter> loadFile(File excelFile) throws IOException, InvalidFormatException { List<Meter> allMeters = new ArrayList<>(); InputStream inputStream = new FileInputStream(excelFile); XSSFWorkbook workbook = new XSSFWorkbook(inputStream); Sheet sheet1 = workbook.getSheetAt(0); Iterator<Row> rows_sheet1 = sheet1.iterator(); if (rows_sheet1.hasNext()) { rows_sheet1.next(); //skip header } while (rows_sheet1.hasNext()) { try { Row currentRow = rows_sheet1.next(); Cell meterNoCell = currentRow.getCell(0); Cell startPeriodCell = currentRow.getCell(1); Cell endPeriodCell = currentRow.getCell(2); Cell previousConsumption = currentRow.getCell(3); Cell currentConsumption = currentRow.getCell(4); Cell periodConsumptionCell = currentRow.getCell(5); meterNoCell.setCellType(CellType.STRING); startPeriodCell.setCellType(CellType.STRING); endPeriodCell.setCellType(CellType.STRING); //Reading values from above_defined cells and filling allMeters list (defined at the begining of the function). //...... //Done } catch (Exception ex) { Logger.getLogger(MetersList.class.getName()).log(Level.SEVERE, null, ex); } } workbook.close(); inputStream.close(); return allMeters;}
2 回答

搖曳的薔薇
TA貢獻1793條經(jīng)驗 獲得超6個贊
首先,我注意到使用任務管理器 (Windows) 或活動監(jiān)視器 (Mac) 進行監(jiān)控是一項愚蠢的工作。這些工具顯示的是保留的堆空間(不是已使用的堆空間)。因此,當我使用 NetBeans 分析監(jiān)視應用程序的內(nèi)存使用情況時,我注意到 GC 工作得非常好并釋放了堆內(nèi)存。
此外,取消引用Workbook
和InputStream
對象 (with =null;
) 加速了 GC 執(zhí)行。
在那之后,我的問題發(fā)生了變化。
關閉這些流后,GC 運行良好,使用的堆空間減少。但是,保留的堆空間將保持不變,不會減少,如下圖所示:
我看了一下這篇文章。綜上所述,需要用到以下JVM參數(shù):
-XX:MinHeapFreeRatio
-XX:MaxHeapFreeRatio
我設置-XX:MaxHeapFreeRatio=40了一段時間后,保留的堆空間被釋放了。

倚天杖
TA貢獻1828條經(jīng)驗 獲得超3個贊
嘗試兩個建議的解決方案,如果其中任何一個對您有幫助,請告訴我們。
對工作簿和 inputStream 使用 finalize() 而不是 close()。
關閉工作簿和 inputStream 后將它們都設置為 null,然后調(diào)用 System.gc();
添加回答
舉報
0/150
提交
取消