【问题标题】:Error: GC overhead limit exceeded in XSSFWorkbook错误:XSSFWorkbook 中超出了 GC 开销限制
【发布时间】:2017-04-22 20:31:29
【问题描述】:

我正在使用 Java Apache POI 库并处理大量的 Excel 表格。大约 10 mb 的数据,包含很多行和列。一个excel文件中还有8-10张不同的工作表。数据不是富文本格式,而是充满了内部函数和公式,例如。 = SUM(A2:A4) 等等我没有任何顾虑。

此图像仅用于说明目的。实际数据中的函数非常不同且非常复杂:

数据包括字符串、数字和布尔值。我关心的只是让 XSSF 将值作为普通文本读取,不包括在 excel 中应用的所有公式或函数。也就是说,在上图中,我只想读取行和列中的值i.e. 10,20,30 etc, Numbers, Total

问题

如果我格式化 excel 工作表并删除所有公式和函数并以简单的富文本格式保存数据,我的代码就会运行。但是,当我不修改 excel 文件并按上述格式保留数据时,我遇到 GC 开销限制超出错误。

我想要什么

我只想按原样阅读充满公式和函数的 excel 文件。当我删除所有公式并将工作表中的文本保持为正常的富文本格式时,我的算法就起作用了。

我尝试了什么

正如其他在线资源和 stackoverflow 中所述,我尝试了以下代码中给出的第一种方法:

fis = new FileInputStream(path);
opc = OPCPackage.open(fis);  
XSSFWorkbook workbook = new XSSFWorkbook(opc);

我首先通过 OPCPackage 传递它,而不是简单地使用 FileInputStream 作为输入。它仍然显示相同的错误并且代码不会在XSSFWorkbook workbook下方执行

然后我对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)) {

              // no idea how to extract sheet like I would do in XSSFWorkbook
              // I only get Sheet name of desired sheet

    } // while ends here

到目前为止,没有什么对我有用,如果我使用XSSFWorkbook,它将抛出 GC 开销限制超出错误。所以目前我手动删除所有公式和函数,然后算法工作,但它不是处理问题的有效方法。任何帮助或建议表示赞赏。

编辑:

正如链接here 中指出的那样,我尝试分配更多内存,但仍然无法正常工作。下面是我尝试分配更多内存的一些快照。

如果我在分配内存时做错了什么,请告诉我。我会做必要的改变。

新编辑

我通过在 Eclipse 中的运行配置中添加 -Xmx8192m 解决了我在下面的 centic 评论中提到的问题。我现在正在研究使用SXSSFWorkbook 解决内存问题的其他方法,如下面的答案中已经讨论过的。

【问题讨论】:

  • @huellif 我尝试分配更多内存,但它不起作用。我还编辑了我的问题。
  • 您显示的内存设置是针对 Eclipse IDE 和 Java Webstart,您实际上是如何启动应用程序的?如果作为 Eclipse 中的应用程序或单元测试,那么您需要在运行配置中调整内存设置,而不是在您自己的代码运行时实际应用它们。
  • 我刚到我的工作场所。到目前为止,我直接从 eclipse 启动我的应用程序。我现在将尝试在运行配置中调整设置。让我们看看它是否有效
  • @centic 我用你的把戏解决了我的问题。刚刚在运行配置中添加了-Xmx8192m。它解决了我的问题,但我希望当我完成我的项目时,它会在我同事的计算机上成功运行。有没有办法让我接受您的评论作为最终答案?

标签: java excel apache-poi


【解决方案1】:

您是否尝试将文件作为 SXSSF 工作簿而不是 XSSF 工作簿打开?

fis = new FileInputStream(path);
opc = OPCPackage.open(fis); 
XSSFWorkbook workbook = new XSSFWorkbook(opc);
SXSSFWorkbook wb = new SXSSFWorkbook(workbook);

https://poi.apache.org/apidocs/org/apache/poi/xssf/streaming/SXSSFWorkbook.html。直接取自他们的 JavaDoc:“这允许写入非常大的文件而不会耗尽内存,因为任何时候只有行的可配置部分保存在内存中”

【讨论】:

  • 是的,我确实尝试过这个,但我的代码在XSSFWorkbook workbook = new XSSFWorkbook(opc); 代码之后立即抛出 GC 限制超出异常。我只是不明白为什么会这样。当我从 excel 文件中删除公式时,我没有问题。我有大量的数据。
  • 嗯。这行得通吗? FileInputStream fis = new FileInputStream(excelFile);工作簿 workBook = new SXSSFWorkbook(200); workBook = WorkbookFactory.create(fis);
  • 我现在试过了,在workBook = WorkbookFactory.create(fis);行之后我得到了同样的错误
【解决方案2】:

发表评论作为答案:

您显示的内存设置适用于 Eclipse IDE 和 Java Webstart,您实际上是如何启动应用程序的?如果作为 Eclipse 中的应用程序或单元测试,那么您需要在运行配置中调整内存设置,而不是在您自己的代码运行时实际应用它们。

【讨论】:

  • 这解决了我的问题。我在 Eclipse 中的运行配置中添加了 -Xmx8192m。谢谢。
猜你喜欢
  • 2010-11-26
  • 1970-01-01
  • 2018-04-10
  • 2021-01-07
  • 2017-11-12
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多