简体   繁体   中英

How to marshall large java objects to xml without heap error?

Currently I am using JAXB marshaller to marshall the large java object and it is working but when i recive the large java object application is throwing the OutOfMemoryError: heap space error.

Can some one let me know how to marshall large java object to xml without heap error.

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

Here is the exact stack error,

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)

I will give you the short and long answer.

Short (practical) answer

You have 20 objects, 15Mb each one. It means that they occupy ~300Mb. Probably XML representation occupies twice more. So, configure you JVM heap to 1 - 2 G and forget continue your development. (use -Xmx1G ) command line option when running JVM.

Longer answer

Why does OOM happens? You serialize object into XML using JAXB that uses DOM. This means that first the system creates DOM representation of your huge object, then it serializes it into textual form. All this requires a lot of memory. You can avoid using JAXB and find other tool for serializing object to XML or write your own code. I am not sure, but try XStream. It is very strong tool and is able to use SAXt at least for parsing, so probably it knows to serialize objects incrementally too. This solution is more scaleable than the first one but requires coding.

BTW: make sure that when your serializing the object you marshal it directly to file (or web resource or other external target) and not to byte array or string.

EDIT

Your latest additions to your question proved my fears. Your problem is not in JAXB serialization but in creating huge string. Why are you doing this? I doubt that you store it in RAM for future use. I believe that you immediately write it to some stream (file, network, whatever - does not matter.) This means that you actually should not create the string at all. Do not use StringWriter and then StringWriter.toString() (where the exception is thrown). If you want to write XML to file use FileWriter directly.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM