java.lang.OutOfMemoryError: GC overhead limit exceeded when loading an xlsx file
java.lang.OutOfMemoryError: GC overhead limit exceeded when loading an xlsx file
我明白这个错误是什么意思,我的程序消耗了太多内存,而且很长一段时间都没有恢复。
发生内存问题时,我的程序正在读取 6,2Mb xlsx
文件。
当我尝试监控程序时,它的内存消耗很快达到 1.2Gb,然后崩溃。读取6,2Mb文件时如何达到1,2Gb?
有没有办法分块打开文件?这样它就不必加载到内存中了?或者任何其他解决方案?
正是这部分导致了它。但既然它是一个图书馆,难道不应该以某种方式巧妙地处理它吗?它只有 200 000 行,只有 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
class。由于数据为XML,可以使用StAX有效处理内容
这是(一种方法)如何从 xlsx 中获取 Inputstream
。
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 处理数据的 examples,但使用 StAX 更好并且同样高效。
我明白这个错误是什么意思,我的程序消耗了太多内存,而且很长一段时间都没有恢复。
发生内存问题时,我的程序正在读取 6,2Mb xlsx
文件。
当我尝试监控程序时,它的内存消耗很快达到 1.2Gb,然后崩溃。读取6,2Mb文件时如何达到1,2Gb?
有没有办法分块打开文件?这样它就不必加载到内存中了?或者任何其他解决方案?
正是这部分导致了它。但既然它是一个图书馆,难道不应该以某种方式巧妙地处理它吗?它只有 200 000 行,只有 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
class。由于数据为XML,可以使用StAX有效处理内容
这是(一种方法)如何从 xlsx 中获取 Inputstream
。
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 处理数据的 examples,但使用 StAX 更好并且同样高效。