java - 在 Java 中解码大型 Xml 文件

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

它不断抛出 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/

相关文章:

xml-parsing - 创建 `Nokogiri::XML` 或 `Nokogiri::HTML` 对象时如何避免创建不重要的空白文本节点

grails - 使用Groovy初始化JAXBContext时,Grails 3.0.8抛出IllegalAnnotationsException的错误1计数

java - 尽管已配对,BluetoothAdapter.getBondedDevices 返回零个设备,为什么?

java - 为什么解析器可以工作,但当我尝试打印它时却返回空数据?

java - 如何创建虚拟 View 以锚定弹出窗口android

java - 使用自定义适配器将 XML 中的数据解析为列表

java - 用 Java 在数据库中保存 XML 文档(Hibernate 和 JAXB 的组合)

java - 如何通过 xsdtojava 在自动生成的 jaxb 元素上添加接口(interface)?

java - 如何使用 ModelMapper 将外键从 dto 映射到实体对象?

java - 与 Java EE 服务器通信的最佳实践