XSSFWorkbook留在内存中

时间:2016-07-28 14:03:51

标签: java excel apache-poi

我正在使用apache pio 3.14版将一些数据导出到excel。问题是它使用了大量内存。使用VisualVM,我注意到oldgen中的数据从800M导出文件从~80M上升到~400M,并保留在那里。如果我一遍又一遍地重复操作,它会不断增长。似乎XSSFWorkbook永远不会被垃圾收集,它保存了excel文件中所有单元格/表格的引用。 我尝试使用SXSSFWorkbook,但内存使用情况类似。 有没有办法减少内存使用?或者我如何处置XSSFWorkbook。我尝试关闭工作簿并将其引用为null,但这没有帮助

1 个答案:

答案 0 :(得分:0)

今天我在申请中看到了同样的问题。包含所有单元格的工作簿落在旧一代中,永远不会被删除。为了分析问题,我创建了一个应用程序,它创建了一个包含10行的工作簿,其中每行有10个单元格。

XSSFWorkbook in Main

然后我尝试将代码移动到一个单独的线程中。

XSSFWorkbook in Runnable

仍有一些对象留在内存中,但工作簿,工作表,行和单元格都消失了。这是一个简化代码示例,用于说明我是如何对其进行测试的。

public static void main(String[] args) {
    Runnable runnable = new Runnable() {
        @Override
        public void run() {
            Workbook workbook = null;
            FileOutputStream fileOutputStream = null;

            try {
                workbook = new XSSFWorkbook();
                Sheet sheet = workbook.createSheet();
                Row row = sheet.createRow(0);
                Cell cell = row.createCell(0);
                cell.setCellValue("test");
                fileOutputStream = new FileOutputStream(new File("/tmp/workbook.xlsx"));
                workbook.write(fileOutputStream);
            } catch (IOException e) {
                e.printStackTrace();
            } finally {
                if (workbook != null) {
                    try {
                        workbook.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }

                if (fileOutputStream != null) {
                    try {
                        fileOutputStream.close();
                    } catch (IOException e) {
                        e.printStackTrace();
                    }
                }
            }
        }
    };

    Thread thread = new Thread(runnable);
    thread.start();

    // Infinite loop to monitor with visualvm
    for(;;);
}