JAXB - unmarshal OutOfMemory:Java堆空间

TyC*_*TyC 8 java xml memory

我目前正在尝试使用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"));
Run Code Online (Sandbox Code Playgroud)

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

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

这是我的XML的样子

<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<!-- -->
<Export xmlns="wwww.foo.com" xmlns:xsi="www.foo1.com" xsi:schemaLocation="www.foo2.com/.xsd">
<!--- --->
<Origin ID="foooo" />
<!---- ---->
<WorkSets>
   <WorkSet>
      <Work>
         .....
      <Work>
         ....
      <Work>
      .....
   </WorkSet>
   <WorkSet>
      ....
   </WorkSet>
</WorkSets>
Run Code Online (Sandbox Code Playgroud)

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

bdo*_*han 10

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

input.xml中

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

<people>
   <person>
       <name>Jane Doe</name>
       <address>
           ...
       </address>
   </person>
   <person>
       <name>John Smith</name>
       <address>
           ...
       </address>
   </person>
   ....
</people>
Run Code Online (Sandbox Code Playgroud)

演示

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);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

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

@XmlRootElement
public class Person {
}
Run Code Online (Sandbox Code Playgroud)


Dav*_*ton 5

您可以使用-Xmxstartup参数增加堆空间.

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