Модераторы: LSD, AntonSaburov
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> sax parser. файл 402 mgb. java heap space error 
V
    Опции темы
olegrolik
Дата 9.4.2009, 10:27 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Не думал, что  возникнет такая ошибка, т.к. SAX парсер предназначается именно для больших потоков данных.
Как бы то ни было, вот код:
Код

package ru.ozonshop.tests;

import java.io.*;
import java.util.*;

import org.xml.sax.*;
import org.xml.sax.helpers.*;
import org.apache.xerces.parsers.SAXParser;

import ru.ozonshop.beans.*;

public class Flour extends DefaultHandler {
    private List<Offer> offers = new ArrayList<Offer>();
    private static List<Category> categories = new ArrayList<Category>();
    private static List<Category> parentCategories = new ArrayList<Category>();
    
    
    String currentTagName = "";
    float amount = 0;
    public void startDocument() {
        System.out.println("начало документа.");
    }
    public void endDocument() {
        System.out.println("конец документа."+offers.size());
    /*    Iterator it = offers.iterator();
        while(it.hasNext()) {
         
         Offer offer = (Offer)it.next();
         System.out.println("url="+offer.getUrl());
         System.out.println("price="+offer.getPrice());
         
         System.out.println("currencyId="+offer.getCurrencyID());
         System.out.println("categoryId=");
         List categId = offer.getCategoryID();
         System.out.println(categId.size());
         Iterator it2 = categId.iterator();
         while(it2.hasNext()) {
             String categ = (String)it2.next();
             System.out.print(categ+". ");
         }
         System.out.println("picture="+offer.getPicture());
         
         System.out.println("delivery="+offer.isDelivery());
         System.out.println("ordering="+offer.getOrdering());
         System.out.println("name="+offer.getName());
         System.out.println("vendor="+offer.getVendor());
         System.out.println("description="+offer.getDescription());
         System.out.println("--------------------------");
        }
        */
    }
    Offer offer = new Offer();
    public void characters(char ch[], int start, int length) {
    //    System.out.println(currentTagName);
    //    System.out.println("ch.length="+ch.length+", start="+start+", length="+length);
    //    String value = new String(ch, start, length);
//        System.out.print("VALUE==============="+value);
        
    //    System.out.println(". flag="+flag+", sFlag="+sFlag);
    /*    if(flag==1 && sFlag.equals("url")) {
            //    System.out.println("!");
            offer.setUrl(value);
            System.out.println("value for url="+value);
            offers.add(offer);
            
    }    */
        String value = new String(ch, start, length);
    //    System.out.println(value);
        if(sFlag.equals("url")) {
            offer.setUrl(new String(value));
        } else if(sFlag.equals("price")) {
            offer.setPrice(new String(value));
        } else if(sFlag.equals("currencyId")) {
            offer.setCurrencyID(new String(value));
        } else if(sFlag.equals("categoryId")) {
            categoryIDList.add(new String(value));
            //System.out.println("characters. size="+categoryIDList.size());
        }
        else if(sFlag.equals("picture")) {    
            offer.setPicture(new String(value));
    //        System.out.println("value for picture="+value);
    //        System.out.println(offer.getPicture());            
        } else if(sFlag.equals("delivery")) {
            offer.setDelivery(Boolean.getBoolean(new String(ch, start, length)));
        } else if(sFlag.equals("ordering")) {
            offer.setOrdering(new String(value));
        } else if(sFlag.equals("name")) {
            offer.setName(new String(value));
        } else if(sFlag.equals("vendor")) {
            offer.setVendor(new String(value));
        } else if(sFlag.equals("description")) {
            offer.setDescription(new String(value));
        }
            
    }
    
    int flag=0;
    int addFlag=0;
    String sFlag="";
    List categoryIDList = new ArrayList();
    public void startElement(String namespaceURI, String localName,
            String qName, Attributes attrs) {
        if(qName.equals("offer")&&flag==0) {
            //System.out.println("startElement->offer");
            flag=1;
            addFlag=0;
        }
        if (qName.equals("url")){
            sFlag = "url";
        }  else if(/*flag==1&&*/qName.equals("price")){
            sFlag = "price";
        } else if(qName.equals("currencyId")) {
            sFlag = "currencyId";
        } else if(qName.equals("categoryId")) {
            sFlag = "categoryId";
        } else if(/*flag==1&&*/qName.equals("picture")){
            sFlag = "picture";
        } else if(qName.equals("delivery")) {
            sFlag = "delivery";
        } else if(qName.equals("ordering")) {
            sFlag = "ordering";
        } else if(qName.equals("name")) {
            sFlag = "name";
        } else if(qName.equals("vendor")) {
            sFlag = "vendor";
        } else if(qName.equals("description")) {
            sFlag = "description";
        }
        
    //    currentTagName = qName;
    //    System.out.println(qName);
        
        /*
        if (localName.equals("category")) {
            Category category = new Category();
            String n = attrs.getValue("","parentId");
            if(n!=null) {
                System.out.println(qName);
                category.setId(qName);
                
            } else if(n==null) {
                
            }
       
        }
        */
    }
    public void endElement(String uri, String name, String qName) {
        if(qName.equals("offer")){
            flag=0;
            offer.setCategoryID(categoryIDList);
  //            System.out.println("endElement size="+categoryIDList.size());
            
  //            System.out.println("endElement size="+categoryIDList.size());
            
            offers.add(offer);
  //            System.out.println("offer.getCategoryID().size()="+offer.getCategoryID().size());
            
            offer=null; offer=new Offer();
        //    categoryIDList = null; categoryIDList = new ArrayList();
        }
        //offer.setPrice(null);
        //offer.setPicture(null);
        /*if(qName.equals("offer")) {
            System.out.println("!!!!!!!!!!!!!!!!!!!!!!");
            addFlag=1;
            flag=0;
        }
        
        sFlag="";
        */
        //flag=0;
    }

  public static void main(String[] args) {
    Flour f = new Flour();
    SAXParser p = new SAXParser();
    p.setContentHandler(f);
    try { p.parse(args[0]); } 
    catch (Exception e) {e.printStackTrace();}
  /*  System.out.println(offers.size());
    Iterator it = offers.iterator();
    while(it.hasNext()) {
     
     Offer offer = (Offer)it.next();
     System.out.println("url="+offer.getUrl());
     System.out.println("picture="+offer.getPicture());
     System.out.println("price="+offer.getPrice());
     System.out.println("--------------------------");
    }
    
    */
  }
}

Ошибка:
Код

Exception in thread "main" java.lang.OutOfMemoryError: Java heap space
    at java.util.Arrays.copyOfRange(Arrays.java:3209)
    at java.lang.String.<init>(String.java:216)
    at ru.ozonshop.tests.Flour.characters(Flour.java:67)
    at org.apache.xerces.parsers.AbstractSAXParser.characters(Unknown Source)
    at org.apache.xerces.impl.dtd.XMLDTDValidator.characters(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanContent(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl$FragmentContentDispatcher.dispatch(Unknown Source)
    at org.apache.xerces.impl.XMLDocumentFragmentScannerImpl.scanDocument(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XML11Configuration.parse(Unknown Source)
    at org.apache.xerces.parsers.XMLParser.parse(Unknown Source)
    at org.apache.xerces.parsers.AbstractSAXParser.parse(Unknown Source)
    at ru.ozonshop.tests.Flour.main(Flour.java:179)


xml-файл доступен по ссылке - http://www.ozon.ru/multimedia/yml/partner/div_book.xml


Может кто знает в чём дело?
PM MAIL   Вверх
Skynin
Дата 9.4.2009, 10:56 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



Увидевши:

Код

else if(qName.equals("categoryId"))
            sFlag = "categoryId";

10 раз

вместо
Код

            sFlag = qName;

и проверки в HashSet на допустимость qName

смотреть больше не хочется smile

Это сообщение отредактировал(а) Skynin - 9.4.2009, 10:57
PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
olegrolik
Дата 9.4.2009, 11:01 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Цитата(Skynin @ 9.4.2009,  10:56)


и проверки в HashSet на допустимость qName


Этот момент не понял.
А насчёт 10 раз - мой косяк.
PM MAIL   Вверх
ecologist
Дата 9.4.2009, 11:14 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 452
Регистрация: 28.2.2007

Репутация: 2
Всего: 9



Можно посмотреть еще StAX - мне даже больше понравилось.
PM MAIL   Вверх
olegrolik
Дата 9.4.2009, 11:42 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Цитата(ecologist @ 9.4.2009,  11:14)
Можно посмотреть еще StAX - мне даже больше понравилось.

StAx позволяет парсить потоки > 400 мегабайт?


Мне кажется, SAX тоже позволяет работать с большими потоками данных (почти уверен smile). Но где-то в коде я накосячил.


Только что попробовал разобрать файл в 42 мегабайта - успешно.

Это сообщение отредактировал(а) olegrolik - 9.4.2009, 11:44
PM MAIL   Вверх
Skynin
Дата 9.4.2009, 11:54 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



Цитата

Только что попробовал разобрать файл в 42 мегабайта - успешно.

А сколько от первоначального объема остается в памяти в виде нужных данных в ArrayList - посчитали?

Если, скажем выбрасываются только xml теги, из 400Мб полезных данных 350, то 
1. нужно подкручивать параметры хипа JVM
2. использовать встроенную базу данных и копировать туда (Apache Derby, H2, ..., )
PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
olegrolik
Дата 9.4.2009, 12:19 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Цитата(Skynin @ 9.4.2009,  11:54)
Цитата

Только что попробовал разобрать файл в 42 мегабайта - успешно.

А сколько от первоначального объема остается в памяти в виде нужных данных в ArrayList - посчитали?

Если, скажем выбрасываются только xml теги, из 400Мб полезных данных 350, то 
1. нужно подкручивать параметры хипа JVM
2. использовать встроенную базу данных и копировать туда (Apache Derby, H2, ..., )

Парсил файл размером в 43 536 988 байт.
В коллекции насчитал 13 969 832 байта.

Думаю соотношение у файла в 400 мегов будет такое же.

Насчёт параметров JVM - я собираюсь поднимать приложение на хостинге, на самом дешёвом тарифе. Не думаю, что там можно увеличить память под мои нужды.

PM MAIL   Вверх
Skynin
Дата 9.4.2009, 12:37 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



Цитата

Насчёт параметров JVM - я собираюсь поднимать приложение на хостинге, на самом дешёвом тарифе. Не думаю, что там можно увеличить память под мои нужды.

Считаем - (13 969 832/43 536 988)*400 = 128,34909Мб

Выясняем - сколько по умолчанию дается.

Если нельзя увеличить - используем встраиваемую БД (или предоставляемую хостером, MySQL или какая у него доступна)
PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
olegrolik
Дата 9.4.2009, 12:52 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Резюме какое?
SAX читает любые потоки данных (звёздочка).
звёздочка - в зависимости от используемой памяти вашей JVM.  smile 
Получается ак? smile 

PM MAIL   Вверх
Skynin
Дата 9.4.2009, 13:00 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 359
Регистрация: 1.7.2007
Где: Харьков

Репутация: 6
Всего: 10



Цитата

Получается ак?

Любой программе нужна память.

Если ее недостаточно в комьютере для реализации алгоритма, то:
либо нужно докупить
либо менять алгоритм

У JVM есть еще ограничение, с расчетом на то что на компьютере может работать масса других програм, которым тоже нужна память: настраиваемый размер разрешенного размера памяти для программы.
Если ее недостаточно для реализации алгоритма, то:
либо нужно увеличить эту квоту
либо менять алгоритм

Причем тут SAX?
Если он, не может докупить памяти, не может увеличить квоту JVM?

Резюме:
Вам нужно либо учиться на программиста, либо бросать это дело,
потому что в данном конкретном случае выделяете в алгоритме памяти  128,34909Мб лично ВЫ, лично Ваш алгоритм, а никакой не SAX или что угодно.

То есть можно взять файл, размером 1 байт, и 134217728 раз добавить в ArrayList это байт и получить OutOfMemory и сделать вывод что функции чтения файла работают неправильно.

Цитата

Получается ак?


Это сообщение отредактировал(а) Skynin - 9.4.2009, 13:05
PM MAIL WWW ICQ Skype GTalk YIM MSN   Вверх
olegrolik
Дата 13.4.2009, 17:44 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Возникла новая проблема. SAX пропускает символы. Некорректно распознаёт тэг categoryId.
например у товара с offerId=4295594, categoryId=109 вместо 1099413

Код

<offer id="4295594" available="true">
        <url>http://url</url>
        <price>1259</price>
        <currencyId>RUR</currencyId>
        <categoryId>1101405</categoryId>
        <categoryId>1099413</categoryId>
        <categoryId>1098339</categoryId>
        <picture>http://picture</picture>
        <delivery>true</delivery>
        <orderingTime>
          <ordering>На складе</ordering>
        </orderingTime>
        <name>имя </name>
        <vendor>Vendor</vendor>
        <description>ваваываываыв</description>
      </offer>



Что здесь может быть?
PM MAIL   Вверх
LSD
Дата 13.4.2009, 17:51 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Leprechaun Software Developer
****


Профиль
Группа: Модератор
Сообщений: 15718
Регистрация: 24.3.2004
Где: Dublin

Репутация: 210
Всего: 538



Цитата(olegrolik @  13.4.2009,  17:44 Найти цитируемый пост)
Что здесь может быть? 

Неправильное использование метода characters(). Этот метод не обязан сразу передавать все данные которые идут внутри тега, он может это следовать несколько последовательных вызовов.


--------------------
Disclaimer: this post contains explicit depictions of personal opinion. So, if it sounds sarcastic, don't take it seriously. If it sounds dangerous, do not try this at home or at all. And if it offends you, just don't read it.
PM MAIL WWW   Вверх
olegrolik
Дата 14.4.2009, 10:23 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Опытный
**


Профиль
Группа: Участник
Сообщений: 309
Регистрация: 25.1.2006

Репутация: нет
Всего: нет



Цитата(LSD @ 13.4.2009,  17:51)
Неправильное использование метода characters(). Этот метод не обязан сразу передавать все данные которые идут внутри тега, он может это следовать несколько последовательных вызовов.

Правда чтоль? smile 

Если серьёзно, то и так понятно, что проблема в этом методе.
Вчера в инете нашёл ответ на мой вопрос
вот он: http://www.coderanch.com/t/432967/XML-Rela...with-SAX-Parser
Надо использовать вместо 
Код

String s = ""; // должно быть объявлено в классе
public void characters(char c[], int start, int length) {
  s = new String(ch, start,length);
}


Код

StringBuffer sb = new StringBuffer(); // должно быть объявлено в классе
public void characters(char c[], int start, int length) {
  sb = sb.append(new String(ch, start,length));
}



Как-то так.
Короче помогло.
PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Java"
LSD   AntonSaburov
powerOn   tux
javastic
  • Прежде, чем задать вопрос, прочтите это!
  • Книги по Java собираются здесь.
  • Документация и ресурсы по Java находятся здесь.
  • Используйте теги [code=java][/code] для подсветки кода. Используйтe чекбокс "транслит", если у Вас нет русских шрифтов.
  • Помечайте свой вопрос как решённый, если на него получен ответ. Ссылка "Пометить как решённый" находится над первым постом.
  • Действия модераторов можно обсудить здесь.
  • FAQ раздела лежит здесь.

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, LSD, AntonSaburov, powerOn, tux, javastic.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Java: Общие вопросы | Следующая тема »


 




[ Время генерации скрипта: 0.0664 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.