java - 如何在没有堆错误的情况下将大型 java 对象编码为 xml?

标签 java xml jaxb marshalling

目前我正在使用 JAXB 编码器来编码大型 Java 对象并且它正在工作但是当我收到大型 Java 对象应用程序时抛出 OutOfMemoryError:堆空间错误。

谁能告诉我如何在没有堆错误的情况下将大型 java 对象编码为 xml。

StringWriter writer = new StringWriter();
JAXBContext.newInstance("packageName").createMarshaller.marshall(myObject,writer);
return writer.toString();

这是确切的堆栈错误,

Caused by: java.lang.OutOfMemoryError: Java heap space
    at java.lang.StringBuffer.ensureCapacityImpl(StringBuffer.java:338)
    at java.lang.StringBuffer.append(StringBuffer.java:114)
    at java.io.StringWriter.write(StringWriter.java:88)
    at java.io.BufferedWriter.flushBuffer(BufferedWriter.java:122)
    at java.io.BufferedWriter.flush(BufferedWriter.java:246)
    at com.ibm.jtc.jax.xml.bind.v2.runtime.MarshallerImpl.cleanUp(MarshallerImpl.java:339)
    at com.ibm.jtc.jax.xml.bind.v2.runtime.MarshallerImpl.write(MarshallerImpl.java:332)
    at com.ibm.jtc.jax.xml.bind.v2.runtime.MarshallerImpl.marshal(MarshallerImpl.java:249)
    at javax.xml.bind.helpers.AbstractMarshallerImpl.marshal(AbstractMarshallerImpl.java:95)
    at com.ibm.xml.xlxp2.jaxb.marshal.MarshallerImpl.marshal(MarshallerImpl.java:210)
    at com.mine.app.util.AppUtility.marshalXMLPayload(Unknown Source)

最佳答案

我会给你简短和长的答案。

简短(实用)回答

您有 20 个对象,每个对象 15Mb。这意味着它们占用约 300Mb。可能 XML 表示占用两倍以上。因此,将您的 JVM 堆配置为 1 - 2 G,然后忘记继续您的开发。 (使用 -Xmx1G)运行 JVM 时的命令行选项。

更长的答案

为什么会出现OOM?您使用使用 DOM 的 JAXB 将对象序列化为 XML。这意味着系统首先创建您的大对象的 DOM 表示,然后将其序列化为文本形式。这一切都需要大量的内存。 您可以避免使用 JAXB 并寻找其他工具将对象序列化为 XML 或编写您自己的代码。我不确定,但试试 XStream。它是非常强大的工具,至少能够使用 SAXt 进行解析,因此它可能也知道以增量方式序列化对象。 此解决方案比第一个解决方案更具可扩展性,但需要编码。

顺便说一句:确保在序列化对象时将其直接编码到文件(或网络资源或其他外部目标),而不是字节数组或字符串。

编辑

您对问题的最新补充证明了我的担忧。 您的问题不在于 JAXB 序列化,而在于创建巨大的字符串。你为什么做这个?我怀疑您是否将其存储在 RAM 中以备将来使用。我相信您会立即将它写入某个流(文件、网络等 - 无关紧要)。这意味着您实际上根本不应该创建该字符串。不要使用 StringWriter 然后使用 StringWriter.toString()(抛出异常的地方)。如果要将 XML 写入文件,请直接使用 FileWriter

关于java - 如何在没有堆错误的情况下将大型 java 对象编码为 xml?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/30025443/

相关文章:

xml - 指定 xsi :type for an local complexType? 是否有效

java - 在 Java 中模拟 Group By Rollup

java - AndroidManifest.xml 中的元数据标记没有正确的值

Android rss库

c# - 如何使用包含&符号的字符串值序列化对象?

java - JAXB 和 XSLT 性能

java - Android Retrofit 带有安全 header 的 Soap 请求信封

java - 相机图像处理

跨类加载器的 Java 8 ScriptEngine

java - 如何忽略 JAX-RS 2.0 客户端中的意外字段?