当前位置: 代码迷 >> java >> java.lang.OutOfMemoryError:加载xlsx文件时,超出了GC开销限制
  详细解决方案

java.lang.OutOfMemoryError:加载xlsx文件时,超出了GC开销限制

热度:67   发布时间:2023-07-25 19:45:16.0

我理解该错误是什么意思,即我的程序占用了太多内存,并且很长一段时间都无法恢复。

发生内存问题时,我的程序仅读取6,2Mb xlsx文件。

当我尝试监视该程序时,它很快就会达到1,2Gb的内存消耗,然后崩溃。 读取6,2Mb文件时如何达到1,2Gb?

有没有一种方法可以分块打开文件? 这样就不必将其加载到内存中了吗? 或其他解决方案?

正是这部分导致了它。 但是由于它是一个库,难道不应该以某种方式巧妙地处理它吗? 它只有20万行,只有3列。 为了将来,我需要它与大约。 100万条记录和更多列...

码:

  Workbook myWorkBook;
        Sheet mySheet;
        if (filePath.contains(".xlsx")) {
            // Finds the workbook instance for XLSX file
             myWorkBook = new XSSFWorkbook(fis);
            // Return first sheet from the XLSX workbook
             mySheet = myWorkBook.getSheetAt(0);
             myWorkBook.close(); // Should I close myWorkBook before I get data from it?
        } 

如果希望使用大型XLSX文件,则需要使用流XSSFReader类。 由于数据是XML,因此可以使用StAX有效地处理内容。

这里是(单程)如何获得Inputstream从XLSX。

OPCPackage opc = OPCPackage.open(file);
XSSFReader xssfReader = new XSSFReader(opc);
SharedStringsTable sst = xssfReader.getSharedStringsTable();
XSSFReader.SheetIterator itr = (XSSFReader.SheetIterator)xssfReader.getSheetsData();
while(itr.hasNext()) {
    InputStream sheetStream = itr.next();
    if(itr.getSheetName().equals(sheetName)) {  // Or you can keep track of sheet numbers
        in = sheetStream;
        return;
    } else {
        sheetStream.close();
    }
}

元素是<row><c> (用于单元格)。 您可以创建一个小的xlsx文件,将其解压缩并检查其中的XML以获取更多信息。

编辑:有一些使用SAX处理数据的 ,但是使用StAX更好而且同样有效。

  相关解决方案