JAXB - unmarshal OutOfMemory: Java Heap Space
Ich versuche momentan, um JAXB verwenden zu unmarshal XML-Datei, aber es scheint, dass die XML-Datei ist zu groß (~500mb) für die unmarshaller zu handhaben. Ich erhalte java.lang.OutOfMemoryError: Java heap space
@
Unmarshaller um = JAXBContext.newInstance("com.sample.xml");
Export e = (Export)um.unmarhsal(new File("SAMPLE.XML"));
Ich vermute, dies ist, weil es versucht, öffnen Sie die große XML-Datei als Objekt, sondern die Datei ist einfach zu groß für die java-heap-space.
Gibt es eine andere, eher "Speicher-effiziente" Methode der Parsen großer XML-Dateien ~ 500mb? Oder vielleicht ein unmarshaller Eigentum, die kann mir helfen, Griff der großen XML-Datei?
Hier ist, was mein XML sieht aus wie
<?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>
Möchte ich unmarshal in den WorkSet-Ebene, noch in der Lage zu Lesen, durch all die Arbeit, die für jeden WorkSet.
Du musst angemeldet sein, um einen Kommentar abzugeben.
Was macht Ihr XML Aussehen? In der Regel für große Dokumente, die ich empfehlen Menschen nutzen einen StAX XMLStreamReader, so dass können Sie das Dokument unmarshallt von JAXB in Stücke schneiden.
input.xml
In das Dokument unten gibt es viele Instanzen der
person
element. Wir können JAXB mit StAXXMLStreamReader
zu unmarshal die entsprechendenPerson
Objekte ein zu einer Zeit zu vermeiden, läuft out of memory.Demo
Person
Statt matching auf das root-element des XML-Dokuments, müssen wir hinzufügen
@XmlRootElement
Anmerkungen auf dem lokalen root des XML-fragment, das werden wir unmarshalling aus.(Person) unmarshaller.unmarshal(xsr);
. Ist das richtig?XMLStreamReader
am Ende des Elements. Dann suchen wir das nächste fragment wollen wir unmarshal aus.while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT)
. Sobald er bekommt es das Programm gibt null. Ich habe meine aktualisierten XML-oben, ist es, weil Sie auf andere Elemente, bevor Sie auf dieWorkSet
oderPerson
in Ihrem Fall?XMLStreamReader
um die Dinge einfach schreiben. Sie können Fragen, dieXMLStreamReader
für den Namen des aktuellen Knotens, um zu sehen, wo Sie in der Traversierung.Könnte man erhöhen heap space über die
-Xmx
startup Arguments.Für große Dateien, SAX-Verarbeitung ist mehr Speicher-effizient, denn es ist ereignisgesteuert, und laden nicht die gesamte Struktur im Speicher.
Ich habe dabei eine Menge Forschung vor allem mit Blick auf das analysieren sehr große Eingabe-sets bequem. Es ist wahr, dass Sie verbinden könnte, StaX und JaxB selektiv analysieren von XML-Fragmenten, aber es ist nicht immer möglich oder vorzuziehen. Wenn Sie interessiert sind, mehr über das Thema bitte haben Sie einen Blick auf:
http://xml2java.net/documents/XMLParserTechnologyForProcessingHugeXMLfiles.pdf
In diesem Dokument beschreibe ich einen alternativen Ansatz, der sehr geradlinig und bequem zu bedienen. Es analysiert beliebig großen Eingabe-sets, während geben Ihnen Zugriff auf Ihre Daten in javabeans-Mode.
Verwenden SAX oder StAX. Aber wenn das Ziel ist, um eine in-memory-Objekt Repräsentation der Datei, müssen Sie noch viel Speicher zu halten den Inhalt so eine große Datei. In diesem Fall, Ihre einzige Hoffnung ist die Erhöhung der heap-Größe über die
-Xmx1024m
JVM-option (stellt die max-heap-Größe auf 1024 MB)SAX, aber Sie müssen erstellen Sie Ihre Export-Objekt selbst
Können Sie versuchen, diese zu dies ist keine gute Praxis
aber seine arbeiten 🙂 wer kümmert sich
http://amitsavm.blogspot.in/2015/02/partially-parsing-xml-using-jaxb-by.html
Andere Weise verwenden, STAX oder SAX, oder was Blaise Doughan sagt, ist auch gut und kann man sagen, ein standard Weg, Aber wenn Sie mit komplexen XML-Struktur, und Sie wollen nicht, um Anmerkungen in Ihren Klassen manuell und mit XJC-tool.
In diesem Fall hilfreich sein könnten.