JAXB – unmarshal OutOfMemory:Java堆空间

我目前正在尝试使用JAXB来解组XML文件,但似乎XML文件太大(~500mb)以供unmarshaller处理。 我一直得到java.lang.OutOfMemoryError: Java heap space @

 Unmarshaller um = JAXBContext.newInstance("com.sample.xml"); Export e = (Export)um.unmarhsal(new File("SAMPLE.XML")); 

我猜这是因为它试图将大型XML文件作为对象打开,但该文件对于Java堆空间来说太大了。

有没有其他更“’内存有效’的方法来解析大型XML文件~500mb? 或者也许是一个unmarshaller属性可以帮助我处理大型XML文件?

这是我的XML的样子

          .....  ....  .....   ....   

我想在WorkSet级别解组,仍然能够读取每个WorkSet的所有工作。

你的XML是什么样的? 通常,对于大型文档,我建议人们使用StAX XMLStreamReader,以便JAXB可以在块中解组文档。

input.xml中

在下面的文档中,有许多person元素的实例。 我们可以使用JAXB和StAX XMLStreamReader解组一个相应的Person对象,以避免内存不足。

   Jane Doe 
...
John Smith
...
....

演示

 import java.io.*; import javax.xml.stream.*; import javax.xml.bind.*; public class Demo { public static void main(String[] args) throws Exception { XMLInputFactory xif = XMLInputFactory.newInstance(); XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("input.xml")); xsr.nextTag(); // Advance to statements element JAXBContext jc = JAXBContext.newInstance(Person.class); Unmarshaller unmarshaller = jc.createUnmarshaller(); while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) { Person person = (Person) unmarshaller.unmarshal(xsr); } } } 

我们需要在XML片段的本地根目录上添加@XmlRootElement注释,而不是匹配XML文档的根元素,我们将从中解组。

 @XmlRootElement public class Person { } 

您可以使用-Xmx启动参数来增加堆空间。

对于大型文件,SAX处理因为事件驱动而具有更高的内存效率,并且不会将整个结构加载到内存中。

我已经做了很多研究,特别是在解析非常大的输入集方面。 确实,您可以将StaX和JaxB组合在一起,以选择性地解析XML片段,但这并不总是可行或更可取。 如果您有兴趣阅读有关该主题的更多信息,请查看:

http://xml2java.net/documents/XMLParserTechnologyForProcessingHugeXMLfiles.pdf

在本文档中,我描述了一种非常简单易用的替代方法。 它解析任意大的输入集,同时让您以javabeans的方式访问您的数据。

使用SAX或StAX 。 但是如果目标是拥有文件的内存中对象表示,那么仍然需要大量内存来保存这样一个大文件的内容。 在这种情况下,您唯一的希望是使用-Xmx1024m JVM选项(将最大堆大小设置为1024 MB)来增加堆大小

SAX但您必须自己构建Export对象

你也可以尝试这种做法,这是一种不好的做法,但它的工作:)谁在乎

http://amitsavm.blogspot.in/2015/02/partially-parsing-xml-using-jaxb-by.html

其他明智的使用STAX或SAX或Blaise Doughan所说的也很好,你可以说一种标准的方式,但是如果你有复杂的XML结构并且你不想手动注释你的类并使用XJC工具。

在这种情况下,这可能会有所帮助。