Большой XML-файл и OutOfMemoryError - PullRequest
2 голосов
/ 02 февраля 2009

Я пытаюсь проанализировать XML-файл размером до 500 МБ в Java. Я пытался использовать SAX, но это дает мне эту ошибку java.lang.OutOfMemoryError: пространство кучи Java на com.sun.org.apache.xerces.internal.util.XMLStringBuffer.append (Неизвестный источник) Вы можете мне помочь? Большое спасибо. Постскриптум Меньшие файлы XML работают просто отлично

Ответы [ 7 ]

11 голосов
/ 02 февраля 2009

Скорее всего, вы неправильно используете SAX или ваше приложение не подходит для потоковой обработки.

Смысл SAX состоит в том, чтобы избежать сохранения всей структуры XML в памяти, но это возможно только в том случае, если вы можете обрабатывать XML небольшими порциями, не сохраняя большого контекста, и если результат обработки либо намного меньше, чем обработанный XML (чтобы он не занимал слишком много памяти) или сам мог быть передан получателю или непрерывно записан на диск.

Редактировать: Также возможно, что у вас просто есть утечка памяти, то есть вы держите данные, которые вам больше не нужны, не позволяя собирать мусор. Если вы используете какие-либо списки, карты или наборы для обработки XML, убедитесь, что все, что вы добавляете к ним при обработке одного фрагмента XML, удаляется, прежде чем запускать следующий фрагмент.

5 голосов
/ 02 февраля 2009

попробуйте использовать Streaming API для XML (новое в java6) это сделано для этого

http://www.javabeat.net/articles/14-java-60-features-part-2-pluggable-annotation-proce-2.html

3 голосов
/ 02 февраля 2009

Вы можете попытаться увеличить размер кучи Java, указав, например,

java -Xmx1024M MyClass

в командной строке (или какое-либо значение будет соответствовать вашему размеру документа).

2 голосов
/ 02 февраля 2009

StAX для версий Java до 6: http://stax.codehaus.org/

1 голос
/ 27 августа 2014

Вы можете проверить ScaleDOM, который позволяет анализировать очень большие файлы XML: https://github.com/whummer/scaleDOM

ScaleDOM имеет небольшой объем памяти из-за отложенной загрузки узлов XML. Он сохраняет только часть XML-документа в памяти и при необходимости перезагружает узлы из исходного файла.

1 голос
/ 03 февраля 2009

Скажем, у вас есть следующая структура 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>

И вы хотите получить все с

Публичный класс { Имя строки; Струнный возраст; }

Ваш обработчик SAX будет выглядеть так

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

}

Как видите, «контент» запоминается только между тегами «age» и «name».

0 голосов
/ 04 мая 2009

Взгляните на Apache Digester.

Вот небольшой учебник

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...