【问题标题】:Out Of Memory Error when marshaling with JAXB使用 JAXB 编组时出现内存不足错误
【发布时间】:2016-01-09 12:11:06
【问题描述】:

我正在使用 JAXB 将 java 对象编组和解组为 xml,反之亦然。 我正在编组的对象具有字节数组属性。如果字节数组的大小很大,我会得到 OOM。

这是我正在做的编组:

StringWriter writer = new StringWriter();
jaxbContext = JAXBContext.newInstance("package name");
Marshaller jaxbMarshaller = jaxbContext.createMarshaller();
jaxbMarshaller.setProperty(Marshaller.JAXB_FRAGMENT, true);
jaxbMarshaller.setProperty(Marshaller.JAXB_FORMATTED_OUTPUT,Boolean.TRUE);
jaxbMarshaller.marshal(myObject, writer);
return writer.toString();

我上线的错误:

jaxbMarshaller.marshal(myObject, writer);

这是堆栈跟踪:

java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOf(Unknown Source)
    at java.lang.AbstractStringBuilder.expandCapacity(Unknown Source)
    at java.lang.AbstractStringBuilder.ensureCapacityInternal(Unknown Source)
    at java.lang.AbstractStringBuilder.append(Unknown Source)
    at java.lang.StringBuffer.append(Unknown Source)
    at java.io.StringWriter.write(Unknown Source)
    at java.io.BufferedWriter.flushBuffer(Unknown Source)
    at java.io.BufferedWriter.flush(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.cleanUp(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.write(Unknown Source)
    at com.sun.xml.internal.bind.v2.runtime.MarshallerImpl.marshal(Unknown Source)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(Unknown Source)

这里是java内存统计:

 uintx AdaptivePermSizeWeight                    = 20              {product}
 intx CompilerThreadStackSize                   = 0               {pd product}
 uintx ErgoHeapSizeLimit                         = 0               {product}
 uintx HeapSizePerGCThread                       = 87241520        {product}
 uintx InitialHeapSize                          := 90006400        {product}
 uintx LargePageHeapSizeThreshold                = 134217728       {product}
 uintx MaxHeapSize                              := 1440743424      {product}
 uintx MaxPermSize                               = 85983232        {pd product}
 uintx PermSize                                  = 21757952        {pd product}
 intx ThreadStackSize                           = 0               {pd product}
 intx VMThreadStackSize                         = 0               {pd product}

非常感谢任何帮助。

【问题讨论】:

  • 你当前的堆和内存设置是什么?您正在运行应用程序还是网络应用程序?
  • @Tim Biegeleisen 你能告诉我如何检查当前的堆和内存设置吗?它是一个网络应用程序
  • 看看here,它讨论了如何做到这一点。也看看here
  • 将可能很大的 myObject 编组到内存中的字符串可能会导致 OOM。为什么不编组到文件?
  • @ShekharKhairnar 你对这篇文章有什么期望——你的问题是什么?如果您期望如何快速解决问题,那么答案将是扩展 JVM 内存。如果您想知道这个问题的根本原因,那么您可能应该阅读 JAXB 的来源,但我认为您可能会偶然发现我发现的错误 stackoverflow.com/questions/31927533/…

标签: java jaxb marshalling


【解决方案1】:

或者,您可以在编组 JAXB 时使用流模式。详情请参考以下帖子:

How to stream large Files using JAXB Marshaller?

这种方法会阻止您的应用在导致此 OutOfMemoryError 的 StringWriter 对象中加载大量数据

【讨论】:

    【解决方案2】:

    请使用Java命令行参数

    -Xms: initial heap size
    -Xmx: Maximum heap size
    

    如果您使用的是 Eclipse IDE。请查看以下链接

    http://stackoverflow.com/questions/2294268/how-can-i-increase-the-jvm-memory
    

    祝你好运

    【讨论】:

      【解决方案3】:

      您可以使用以下 vm args 来增加 jvm 内存。

      -vmargs
      -Xmx512m
      -XX:MaxPermSize=384m
      

      同样,要指定的值取决于 RAM 内存的大小。上述值对于 3GB RAM / 32 位的机器是最佳的

      这些 vm 参数需要作为命令行参数传递给您的 java 应用程序。如果您使用的是 eclipse,请在运行配置中指定。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2016-10-10
        • 1970-01-01
        • 1970-01-01
        • 2016-07-23
        • 2012-05-15
        • 1970-01-01
        相关资源
        最近更新 更多