在这段代码中,我使用 Apache POI 库加载了一个大小为 10MB 的 Excel 文件。这消耗了近 2GB 的内存。遍历所有行后,我终于调用了 close 方法。但是,GC 似乎没有释放此流和对象消耗的空间。并且仍然使用 2GB + 400MB 的内存。有任何想法吗?这是我的代码: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条经验 获得超6个赞
首先,我注意到使用任务管理器 (Windows) 或活动监视器 (Mac) 进行监控是一项愚蠢的工作。这些工具显示的是保留的堆空间(不是已使用的堆空间)。因此,当我使用 NetBeans 分析监视应用程序的内存使用情况时,我注意到 GC 工作得非常好并释放了堆内存。
此外,取消引用Workbook
和InputStream
对象 (with =null;
) 加速了 GC 执行。
在那之后,我的问题发生了变化。
关闭这些流后,GC 运行良好,使用的堆空间减少。但是,保留的堆空间将保持不变,不会减少,如下图所示:
我看了一下这篇文章。综上所述,需要用到以下JVM参数:
-XX:MinHeapFreeRatio
-XX:MaxHeapFreeRatio
我设置-XX:MaxHeapFreeRatio=40了一段时间后,保留的堆空间被释放了。
倚天杖
TA贡献1828条经验 获得超3个赞
尝试两个建议的解决方案,如果其中任何一个对您有帮助,请告诉我们。
对工作簿和 inputStream 使用 finalize() 而不是 close()。
关闭工作簿和 inputStream 后将它们都设置为 null,然后调用 System.gc();
添加回答
举报
0/150
提交
取消