我正在尝试将大小约为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对象。
答案 0 :(得分:1)
您解析的方式,XML的所有数据最终都将转换为最终将在内存中的Java类层次结构。
为避免大文件出现内存问题,您可以:
这将对如何处理XML数据施加一些限制,因为它们永远不会一次全部可用。 如果后处理发生在一些合理大小的XML块中,那么它不是问题,因为你可以在内存中做到这一点。 如果后处理需要在整个XML上进行,一个选项是将数据加载到数据库中并在那里进行后处理。