我正在尝试将大小约为 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);
}
它不断抛出 Caused by: java.lang.OutOfMemoryError: 超出任何较小堆的 GC 开销限制。如果我解析整个文件,我将拥有 330 万个 XYZ 对象。那么有没有一种方法可以让我将这些对象保留在内存中,因为我需要对这些对象进行一些后处理,因为后处理依赖于多个 XYZ 对象。
最佳答案
按照您的解析方式,XML 的所有数据最终都将转换为 Java 类层次结构,并最终存储在内存中。
为了避免大文件出现内存问题,您可以:
- 直接使用事件驱动的SAX解析器,几乎不消耗内存。
- 通过 JAXB 使用部分解码
这将对处理 XML 数据的方式施加一些限制,因为它们永远不会同时可用。 如果后处理发生在 XML 的一些合理大小的 block 中,那么这不是问题,因为您可以在内存中执行此操作。 如果需要对整个 XML 进行后处理,一种选择是将数据加载到数据库中并在那里进行后处理。
关于java - 在 Java 中解码大型 Xml 文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/50566163/