当前位置: 首页 > 知识库问答 >
问题:

关闭java InputStream [duplicate]后,内存没有释放

阳宾实
2023-03-14

在这段代码中,我使用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个答案

罗祺
2023-03-14

尝试两个建议的解决方案,并告诉我们其中是否有对您有帮助的。

>

  • 对于工作簿和inputStream,使用finalize()而不是end()。

    关闭workbook和inputStream后将它们都设置为null,然后调用system . GC();

  • 逄兴昌
    2023-03-14

    首先,我注意到使用任务管理器(Windows)或活动监视器(Mac)进行监控是一项愚蠢的工作。这些工具显示的是保留的堆空间(而不是使用的堆空间)。因此,当我使用NetBeans分析监控应用程序的内存使用时,我注意到GC工作得非常好,并且释放了堆内存。

    此外,取消对WorkbookInputStreamobjects的引用(

    从那以后,我的问题变了。

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

    -XX:MinHeapFreeRatio
    -XX:MaxHeapFreeRatio
    

    我设置了-XX:MaxHeapFreeRatio=40,过了一会儿,保留的堆空间被释放了。

     类似资料:
    • 我正在创建一个应用程序,当我单击一个按钮时,它将在new中打开一个表。但我的问题是,当我关闭该表的时,应用程序不会释放内存。JavaFX有什么问题吗?还是我得做点别的? 我尝试在该阶段结束时将所有内容设置为空,但仍然没有释放内存。 表的舞台上的关闭事件: 表视图; 舞台我的舞台; 我已经创建了一个名为replaceScene方法来使用文件为Stage加载场景。它将返回它的控制器和设置的场景进入舞台

    • 我有以下代码

    • 问题内容: 我一直在对我们的一个宠物项目进行代码审查(通常使用诸如FindBugs之类的工具),并且FindBugs将以下代码标记为错误的(伪代码): 错误是此代码可能不会释放资源。我发现ResultSet和Statement没有关闭,所以我最终将它们关闭: 但是我在许多项目(来自许多公司)中遇到了上述模式,没有人关闭ResultSets或Statements。 关闭连接时,是否关闭了Result

    • 我在Jpa存储库中使用Spring Boot。我在循环中保存一些记录,在保存所有记录后,会打印下面的异常。 JAVAsql。SQLRecoverableException:oracle的Instruço Fechada。jdbc。驾驶员OracleClosedStatement。oracle上的getMaxRows(OracleClosedStatement.java:3578)~[ojdbc6-

    • 我正试着写这段代码 我尝试了许多方法来修复它,但都不起作用:(

    • 我使用以下Java代码打印PDF文档: 控制台上的输出是: 为什么我会收到这个警告?