Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/excel/29.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java Apache POI超出了GC开销限制_Java_Excel_Garbage Collection_Apache Poi - Fatal编程技术网

Java Apache POI超出了GC开销限制

Java Apache POI超出了GC开销限制,java,excel,garbage-collection,apache-poi,Java,Excel,Garbage Collection,Apache Poi,我有13个.xlsx文件,每个文件大约有1000行。现在我想用一张纸把它合并成一个.xlsx文件。我在这里使用代码 这是我的代码(改动很少,addSheet方法没有改变) 我能做什么?为什么会发生这种情况以及如何防止这种情况?发生此问题的原因如下 java.lang.OutOfMemoryError:GC开销限制超出错误是JVM表示应用程序花费太多时间进行垃圾收集而结果太少的一种方式。默认情况下,如果JVM花费超过总时间的98%进行GC,并且在GC之后仅恢复了不到2%的堆,则JVM将配置为抛出

我有13个.xlsx文件,每个文件大约有1000行。现在我想用一张纸把它合并成一个.xlsx文件。我在这里使用代码

这是我的代码(改动很少,addSheet方法没有改变)


我能做什么?为什么会发生这种情况以及如何防止这种情况?

发生此问题的原因如下

java.lang.OutOfMemoryError:GC开销限制超出错误是JVM表示应用程序花费太多时间进行垃圾收集而结果太少的一种方式。默认情况下,如果JVM花费超过总时间的98%进行GC,并且在GC之后仅恢复了不到2%的堆,则JVM将配置为抛出此错误。

如果您只是想忽略此问题,可以设置以下vm选项:

-XX:-UseGCOverheadLimit
有关更多信息,请参阅

还可以使用以下开关为应用程序分配更多堆内存。在您的应用程序上运行一段时间的试验,并确定有多少内存适合您的应用程序

-Xms128m -Xmx512m(these switches sets the initial heap memory size to 128mb and Max memory to 512mb)

试着分配更多的内存

java -Xmx8192m
您还可以尝试一次合并一个xlsx文件,而不是一次加载所有xlsx文件

您还可以将此行移动到for循环中:

excellFile1.close();

因此,您可以立即关闭它。

POI是出了名的内存不足,因此在处理大型Excel文件时,内存不足并不少见


当您能够加载所有原始文件并且只在编写合并文件时遇到问题时,您可以尝试使用
SXSSFWorkbook
而不是
XSSFWorkbook
,并在添加一定量的内容后进行定期刷新(请参阅
org.apache.poi.xssf.streaming
-package的poi文档)。通过这种方式,您不必将生成的整个文件保存在内存中,而只需保存一小部分。

如果您可以避免使用方便但占用大量内存的工作簿API,请使用逐行处理数据的流逻辑,这将大大提高内存效率

尤其要特别注意以下各项的使用: XSSFReader.SheetIterator,用于在图纸上循环

最后,请仔细看看API:XSSFSheetXMLHandler的用法。 用于使用图纸处理行

请参阅此项目的代码:

您可以通过创建自己的行来定义要如何处理每行: 新谢德勒

这非常类似于SAX解析,它不会占用您的ram一点时间


是否可以不更改虚拟机设置?如果没有,您能推荐一些其他库来处理这个问题而不超过GC限制吗?我想库不是问题,因为您在内存中保存了大量数据,我建议您查看源代码,通过源代码可以优化解决方案和/或使用-Xms-Xmx switches.Hm修改应用程序的堆大小分配。这两种选择都没有帮助我解决这个问题。该文件仅为2.9M。读取其他文件时没有任何问题。。。
java -Xmx8192m
excellFile1.close();
 private void readSheet(StylesTable styles, ReadOnlySharedStringsTable sharedStringsTable,
      InputStream sheetInputStream) throws IOException, ParserConfigurationException, SAXException {

    SAXParserFactory saxFactory = SAXParserFactory.newInstance();
    XMLReader sheetParser = saxFactory.newSAXParser().getXMLReader();

    ContentHandler handler =
        new XSSFSheetXMLHandler(styles, sharedStringsTable, sheetContentsHandler, true);

    sheetParser.setContentHandler(handler);
    sheetParser.parse(new InputSource(sheetInputStream));
  }