为了账号安全,请及时绑定邮箱和手机立即绑定

关闭 java InputStream 后,内存未释放

关闭 java InputStream 后,内存未释放

不负相思意 2021-08-13 17:10:05
在这段代码中,我使用 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 工作得非常好并释放了堆内存。

此外,取消引用WorkbookInputStream对象 (with =null;) 加速了 GC 执行。

在那之后,我的问题发生了变化。

关闭这些流后,GC 运行良好,使用的堆空间减少。但是,保留的堆空间将保持不变,不会减少,如下图所示:

//img1.sycdn.imooc.com//6116370e0001147c15440879.jpg

我看了一下这篇文章。综上所述,需要用到以下JVM参数:


-XX:MinHeapFreeRatio

-XX:MaxHeapFreeRatio

我设置-XX:MaxHeapFreeRatio=40了一段时间后,保留的堆空间被释放了。


查看完整回答
反对 回复 2021-08-13
?
倚天杖

TA贡献1828条经验 获得超3个赞

尝试两个建议的解决方案,如果其中任何一个对您有帮助,请告诉我们。

  1. 对工作簿和 inputStream 使用 finalize() 而不是 close()。

  2. 关闭工作簿和 inputStream 后将它们都设置为 null,然后调用 System.gc();


查看完整回答
反对 回复 2021-08-13
  • 2 回答
  • 0 关注
  • 825 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信