用Java解组大型Xml文件

时间:2018-05-28 12:11:12

标签: java xml-parsing jaxb

我正在尝试将大小约为6Gb的大型xml文件解组为java对象。下面是我用来解析大文件的实现。它仅适用于20Gb堆空间。我想进一步减少内存占用量。

XMLInputFactory xif = XMLInputFactory.newInstance();
XMLStreamReader xsr = xif.createXMLStreamReader(new FileReader("abc.xml"));
xsr.nextTag();
long addEntity = 0;
long unmarshalEntity = 0;

JAXBContext jc = JAXBContext.newInstance(XYZ.class);
Unmarshaller unmarshaller = jc.createUnmarshaller();
while(xsr.nextTag() == XMLStreamConstants.START_ELEMENT) {
    long start1 = System.currentTimeMillis();
    XYZ sample = (XYZ) unmarshaller.unmarshal(xsr);
}

它不断抛出由以下引起:java.lang.OutOfMemoryError:对于任何较小的堆超出了GC开销限制。如果我解析整个文件,我有330万个XYZ对象。因此,有一种方法可以设法在内存中保留这些对象,因为我需要对这些对象进行一些后期处理,因为后期处理依赖于多个XYZ对象。

1 个答案:

答案 0 :(得分:1)

您解析的方式,XML的所有数据最终都将转换为最终将在内存中的Java类层次结构。

为避免大文件出现内存问题,您可以:

  • 直接使用事件驱动的SAX解析器,几乎不消耗任何内存。
  • 对JAXB使用部分解组

这将对如何处理XML数据施加一些限制,因为它们永远不会一次全部可用。 如果后处理发生在一些合理大小的XML块中,那么它不是问题,因为你可以在内存中做到这一点。 如果后处理需要在整个XML上进行,一个选项是将数据加载到数据库中并在那里进行后处理。