【问题标题】:Java out of memory when trying to parse a XML file尝试解析 XML 文件时 Java 内存不足
【发布时间】:2015-03-16 13:16:14
【问题描述】:

我有一个相当大的 XML 文件(~280 MB),并且 XML 文件中的每一行都有很多属性,我想从中提取 3 个属性并将其存储在某个地方。但是当我这样做时,我的内存不足。我的代码如下所示:

File xmlFile = new File(xml);
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = null;
try {
    doc = dBuilder.parse(xmlFile);
} catch (SAXException e) {
    e.printStackTrace();
} catch (IOException e) {
    e.printStackTrace();
}

NodeList nList = doc.getElementsByTagName("row");
for (int index = 0; index < nList.getLength(); index++) {
    Node nNode = nList.item(index);
    if (nNode.getNodeType() == Node.ELEMENT_NODE) {
        System.out.print("F1 : " + 
            nNode.getAttributes().getNamedItem("F1").getTextContent());
        System.out.print(" F2: " + 
            nNode.getAttributes().getNamedItem("F2").getTextContent());
        System.out.println(" F3: " + 
            nNode.getAttributes().getNamedItem("F3").getTextContent());
    }
}

这是我得到的错误:

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at com.sun.org.apache.xerces.internal.dom.DeferredDocumentImpl.getNodeObject(DeferredDocumentImpl.java:974)
    at com.sun.org.apache.xerces.internal.dom.DeferredElementImpl.synchronizeData(DeferredElementImpl.java:121)
    at com.sun.org.apache.xerces.internal.dom.ElementImpl.getTagName(ElementImpl.java:314)
    at com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl.nextMatchingElementAfter(DeepNodeListImpl.java:199)
    at com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl.item(DeepNodeListImpl.java:146)
    at com.sun.org.apache.xerces.internal.dom.DeepNodeListImpl.getLength(DeepNodeListImpl.java:117)
    at Parser.parsePosts(Parser.java:55)
    at Parser.main(Parser.java:72)

如何更改它以防止占用过多空间?

编辑: 使用 SAX 编写了一个新的解析器,似乎完成了工作。代码是:

try {

        SAXParserFactory factory = SAXParserFactory.newInstance();
        SAXParser saxParser = factory.newSAXParser();

        DefaultHandler handler = new DefaultHandler() {
            public void startElement(String uri, String localName,String qName, 
                    Attributes attributes) throws SAXException {
                System.out.print(attributes.getValue("F1") + " ");
                System.out.print(attributes.getValue("F2") + " ");
                System.out.println(attributes.getValue("F3"));
            }
        };

        saxParser.parse("file.xml", handler);

    } catch (Exception e) {
        e.printStackTrace();
    }

【问题讨论】:

  • 你必须使用 DOM API 吗?这一次将整个文件加载到内存中,没有办法绕过它。但是您可以改用 SAX 之类的东西,但它不会。
  • 我不必使用它。我只是在谷歌上搜索并找到了 DOM。我愿意使用任何最有效的方法。
  • 查找 SAX,它可能适合您的需求。

标签: java xml


【解决方案1】:

有两种方法可以解决您的问题。您可以增加应用程序的最大内存或使用 sax 解析 xml 文件。

【讨论】:

  • 完美运行,猜猜您的输入文件是否为,例如:1.8GB,然后使用 DOM 解析器将需要 5GB+ 哇!不过使用 SAX 时效果很好。
【解决方案2】:

在运行时尝试参数-Xmx&lt;size&gt; 以增加堆的大小。

例如,java -Xmx500m &lt;filename&gt;

【讨论】:

    【解决方案3】:

    您将不得不增加 Java VM 的内存限制:设置 -Xmx=2048 或其他类似的足够大的值。

    【讨论】:

      猜你喜欢
      • 2011-12-25
      • 1970-01-01
      • 1970-01-01
      • 2016-06-25
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多