【问题标题】:OutOfMemoryError while doing docx comparison using docx4j使用 docx4j 进行 docx 比较时出现 OutOfMemoryError
【发布时间】:2011-09-05 12:45:57
【问题描述】:

在我的应用程序中,我正在比较两个 docx 文件并创建一个 html 比较文件,当我尝试使用 150 或 170 行以下的文件时,没有问题,而我尝试比较 200 行或更多的大文件然后那个时候它显示了

java.lang.OutOfMemoryError: Java heap space error,

有人可以帮忙吗?

【问题讨论】:

  • 您为 java 运行时留出了多少内存空间?尝试增加内存:)
  • 请详细说明您使用的方法(基于缓冲或基于流或基于通道)
  • 我已经尝试在 tomcat catalina.bat 文件中增加 jvm 大小,现在我给了 512m,我正在使用 javax.xml.transform.stream.StreamResult 这个类并再次使用 HtmlExporterNG2 类转换将文档与 html 文件进行比较。
  • 你是在比较过程中内存不足,还是在html转换过程中耗尽了内存?你确定你正确地为 Tomcat 指定了 -Xmx 吗?您要比较的源 docx 有多少页?
  • 执行比较方法本身时出现错误,我正在比较 10 页 docx 文件。这是 catalina 文件中的格式

标签: java docx4j


【解决方案1】:

您的内存不足是因为您没有使用 Docx4jDriver 类,这使得通过首先执行段落级别的差异来解决差异问题。

像这样使用它:

        Body newerBody = ((Document)newerPackage.getMainDocumentPart().getJaxbElement()).getBody();
        Body olderBody = ((Document)olderPackage.getMainDocumentPart().getJaxbElement()).getBody();

        // 2. Do the differencing
        java.io.StringWriter sw = new java.io.StringWriter();
        Docx4jDriver.diff( XmlUtils.marshaltoW3CDomDocument(newerBody).getDocumentElement(),
                        XmlUtils.marshaltoW3CDomDocument(olderBody).getDocumentElement(),
                           sw);

        // 3. Get the result
        String contentStr = sw.toString();
        System.out.println("Result: \n\n " + contentStr);
        Body newBody = (Body) org.docx4j.XmlUtils
                        .unmarshalString(contentStr);

【讨论】:

  • 我改变了我的代码,现在我正在使用 Docx4jDriver,我正在做段落级别的比较,但它仍然在 150 行之前的 330 行之后显示堆内存错误。
【解决方案2】:

您可以使用 -Xmx 和 -Xmx 作为 VM 参数来增大堆空间

这里更多关于Heap Size Tuning或这里Heap size

【讨论】:

  • 我已经尝试在 tomcat catalina.bat 文件中增加 jvm 大小,现在我给了 512m,我正在使用 javax.xml.transform.stream.StreamResult 这个类并再次使用 HtmlExporterNG2 类转换比较文档到 html 文件
  • 尝试使用 XSS 增加堆栈大小(尝试例如:-Xmx512M -Xss1024K)example from here 并且我个人在我的大项目中也增加了初始 Java 堆大小(-Xms256m)
  • 我尊重您对我的问题的关注,并且在我的 catalina.bat 文件中,这种格式的 size 属性 JAVA_OPTS="-Djava.awt.headless=true -Dfile.encoding=UTF-8 -server -Xmx512M -Xss1024K -XX:NewSize=512m -XX:MaxNewSize=512m -XX:PermSize=512m -XX:MaxPermSize=1024m -XX:+DisableExplicitGC"
  • 您很可能会用完 Perm-Space,以后尝试更好地阅读您的异常 ;D 这个开关:-XX:MaxPermSize=1024m 是最重要的一个。如果你做错了什么,Catalina 不应该启动而是发出一个错误。
【解决方案3】:

尝试使用命令行参数-Xmx<maximum heap size>-Xms<minimum heap size> 增加Java 堆大小。

同样在您的代码中,测试您是否确实增加了以下堆大小:

long heapSize = Runtime.getRuntime().totalMemory();
System.out.println("Heap Size = " + heapSize);

在第 117 行调用 Differencer.diff 之前执行此操作。

【讨论】:

    【解决方案4】:

    尝试分析您的应用程序,而不是做出假设或智能猜测。您可以使用 Jdk 附带的 visualvm 或控制台。

    此外,您可以使用 jmap 对您的应用程序进行堆转储,然后使用 jhat 或 eclipse mat(我更喜欢这个,谷歌一下)来查看消耗内存的内容并注意任何异常行为。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多