Java 大XML文件和OutOfMemoryError

Java 大XML文件和OutOfMemoryError,java,xml,memory,parsing,out-of-memory,Java,Xml,Memory,Parsing,Out Of Memory,我试图用java解析一个高达500 mb的XML文件。我试图使用SAX,但它给了我这个错误 java.lang.OutOfMemoryError:java堆空间 位于com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append(未知源) 你能帮助我吗? 谢谢。 另外,较小的XML文件可以正常工作尝试使用XML流API(java6中新增) 它是为这样做而设计的 您可以通过指定 java -Xmx1024M MyClass 在命令行上

我试图用java解析一个高达500 mb的XML文件。我试图使用SAX,但它给了我这个错误 java.lang.OutOfMemoryError:java堆空间 位于com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append(未知源) 你能帮助我吗? 谢谢。
另外,较小的XML文件可以正常工作

尝试使用XML流API(java6中新增) 它是为这样做而设计的


您可以通过指定

java -Xmx1024M MyClass

在命令行上(或任何适合文档大小的值)。

很可能您没有正确使用SAX,或者您的应用程序不适合流处理

SAX的全部要点是避免将整个XML结构保留在内存中,但这只有在您可以在不保留太多上下文的情况下以小块的方式处理XML,并且处理的结果比处理的XML小得多(因此也不会占用太多内存)时才有可能或者可以将其自身传递给收件人或连续写入磁盘


编辑:也有可能是内存泄漏,即,您保留了不再需要的数据,从而阻止了它被垃圾收集。如果使用任何列表、映射或集合来处理XML,请确保在处理一个XML块时添加到这些列表、映射或集合中的任何内容在开始下一个块之前都已删除。

StAX for Java versions pre-6:
假设您具有以下XML结构:

<?xml version="1.0"?>
<list>
  <item>
    <name>Alpha</name>
    <age>10</age>
  </item>
  <item>
    <name>Beta</name>
    <age>20</age>
  </item>
  <!-- many many items -->
</list>

如您所见,“内容”仅在“年龄”和“姓名”标记之间存储。

看看Apache Digester


您可能想查看ScaleDOM,它允许解析非常大的XML文件:


由于XML节点的延迟加载,ScaleDOM的内存占用很小。它只将XML文档的一部分保存在内存中,并在必要时从源文件重新加载节点。

我还对500MB XML文件中存储的内容感兴趣!?您的XML是否包含非常大的文本(比如说,10个百万字符)而没有插入元素?我不知道为什么…是一个学校项目。文件在这里,绝对正确。我可以用SAX解析超过2GB的XML文件。
public class MyHandler extends DefaultHandler
{
 Item current=null;
 StringBuilder content=null;
 @Override
    public void startElement(String uri, String localName, String name,
                    Attributes attributes) throws SAXException {
            if(     name.equals("item")
                  {
                  current= new Item();
                  }
            else if(name.equals("name") || name.equals("age"))
                  {
                  content= new StringBuilder();
                  }
            }

     @Override
    public void endElement(String uri, String localName, String name)
                    throws SAXException
            {
            if(name.equals("item"))
                    {
                   //DO SOMETHING WITH current
                    System.out.println(current);
                    current=null;
                    }
             else if(name.equals("name"))
                    {
                    current.name= content.toString();
                    }
             else if(name.equals("age"))
                    {
                    current.age= content.toString();
                    }
             content=null;
             }

    @Override
    public void characters(char[] ch, int start, int length)
                    throws SAXException {
            if(content!=null)
                    {
                    content.append(ch,start,length);
                    }
            }

}