Почему моя программа Android продолжает выдавать ошибку OutOfMemory - PullRequest
0 голосов
/ 06 января 2012

Привет, ребята. У меня проблема с приложением, связанным с Java-библиотекой Lucene, и я не знаю, в чем именно заключается ошибка

. Вот пример консоли ошибок

ОШИБКА / AndroidRuntime (25909): java.lang.OutOfMemoryError: (размер кучи = 32775 КБ, выделенный = 30112 КБ, размер растрового изображения = 0 КБ)/ AndroidRuntime (25909): в org.apache.lucene.index.FreqProxTermsWriterPerField $ FreqProxPostingsArray.newInstance (FreqProxTermsWriterPerField.java:204). ERROR / AndroidRuntime.48.java: 440) ОШИБКА / AndroidRuntime (25909): в org.apache.lucene.index.DocInverterPerField.processFields (DocInverterPerField.java:172) Ошибкаlucene.index.DocumentsWriter.updateDocument (DocumentsWriter.java:766) ОШИБКА / AndroidRuntime (25909): по адресу org.apache.lucene.index.IndexWriter.addDocument (IndexWriter.java:2067) ERROR / AndroidRuntime: 25 или 909 (время выпуска 990)apache.lucene.index.IndexWriter.addDocument (IndexWriter.java:2041)

и это говорит о том, что поле индексатора и я не знаю, что это такое

, поэтому вы, ребята, можете мне помочь?Я буду признателен за ваш ответ

, и вот мой код

public class CalculateWeightPage {

protected static Crawlers crawlers;
protected static StopWordsAndStemmer stemmer;
protected static CountWords countWords;
protected static StringSplitter splitter;
protected static ShortingStringArray shortingStringArray;

public static String[][] calulateRelevancePage(String[][] wkt,String urlPage) {

    // 1.1.Defining parameters
    int p = 0;
    int count = 0;
    int count2 = 0;
    String title = "";
    String body = "";
    int titleFreq = 0;
    int bodyFreq = 0;
    String[][] wkp = null ;
    int newTf = 0;
    int y = 0;
    int counter = 0;
    try {



        // 1.2.Extracting the text body and title from webPage
        Map bodyTitle = crawlers.extractBodyAndTitle(urlPage);

        if(bodyTitle.containsKey("title")){

            title = stemmer.removeStopWordsAndStem(((String) bodyTitle.get("title")).toLowerCase());
            body = stemmer.removeStopWordsAndStem(((String) bodyTitle.get("body")).toLowerCase());

            // 1.4.Making a list containing unique words from text title and body
            List bodyTitleUnique = splitter.StringUnique(body);

            int sizeList = bodyTitleUnique.size();
            wkp =  new String[sizeList][2];

            // 1.5.Calculating each tf 
            for (int r = 0; r < sizeList; r++) {
                titleFreq = 0;
                bodyFreq = 0;
                // 1.5.1.Calculating tf in title
                titleFreq = countWords.calculate(title, bodyTitleUnique.get(r).toString());

                // 1.5.2.Calculating tf in body
                bodyFreq = countWords.calculate(body, bodyTitleUnique.get(r).toString());

                if (!(titleFreq == 0)) {
                    newTf = (titleFreq * 2) + (bodyFreq - titleFreq);
                } else {
                    newTf = titleFreq + bodyFreq;
                }

                // 1.6.Inserting the result into string array
                if(!(newTf == 0)){
                    wkp[r][0] = bodyTitleUnique.get(r).toString();
                    wkp[r][1] = String.valueOf(newTf);
                }
            }

        }else{
            return wkp;
        }

    } catch (Exception e) {
        // TODO: handle exception
    }
    return wkp;

}

}

, и это для второго кода

public class CountWords {
CountWords() {

}

protected static StopWordsAndStemmer stemmer;

public static int calculate(String txt, String keyword) {

    StopAnalyzer analyzer = new StopAnalyzer(Version.LUCENE_CURRENT);
    RAMDirectory idx = new RAMDirectory();
    int counts = 0;
    int count = 0;
    try {
        IndexWriter writer = new IndexWriter(idx, analyzer, true,
                IndexWriter.MaxFieldLength.UNLIMITED);

        Document doc = new Document();

        //String text1 = stemmer.removeStopWordsAndStem(txt.toLowerCase());

        writer.addDocument(createDocument("", txt));

        writer.optimize();
        writer.close();

        Searcher searcher = new IndexSearcher(idx);

        IndexReader ir = IndexReader.open(idx);
        TermDocs termDocs = ir.termDocs(new Term("content", keyword.toLowerCase()));

        while (termDocs.next()) {
            count = count + termDocs.freq();
        }
        //counts = count(count);

        searcher.close();

    } catch (IOException ioe) {
        ioe.printStackTrace();
    }
    return count;

}

private static Document createDocument(String title, String content) {
    Document doc = new Document();
    doc.add(new Field("content", new StringReader(content)));
    return doc;
}

private static int search(Searcher searcher, String queryString)throws ParseException, IOException {

    StandardAnalyzer analyzer = new StandardAnalyzer(Version.LUCENE_CURRENT);
    QueryParser parser = new QueryParser(Version.LUCENE_CURRENT, "content",analyzer);
    Query query = parser.parse(queryString);

    TopScoreDocCollector collector = TopScoreDocCollector.create(10, true);
    searcher.search(query, collector);

    return collector.getTotalHits();
}

public static Integer count(int count) {
    if (count == 0) {
        count = 1;
    } else {
        count = count;
    }
    return count;
}

}

1 Ответ

0 голосов
/ 22 февраля 2012

Вполне вероятно, что вы получите эту ошибку, потому что все данные, которые вам нужны, не могут поместиться в памяти.

Однако ваше решение выглядит немного перегруженным: вам не нужен Lucene для вычисления частотных терминов в памяти (метод вычисления CountWords), вам просто нужно проанализировать входные данные и сохранить частоты в карте HashMap<String, Integer>.

Более того, хотя ваш код может работать, в вашем коде есть вещи, которые выглядят некорректно:

  • Вы должны вызвать commit до оптимизации, чтобы сегменты создавались до оптимизации (хотя оптимизация наверняка будет бессмысленной, потому что у вас будет только один сегмент),
  • вы открываете один поисковик индекса и одно читатель индекса в одном и том же каталоге, но при открытии поискового индекса открывается устройство чтения индекса, поэтому на самом деле будут открыты два эквивалентных считывателя, хотя требуется только один,
  • Вы закрываете поисковик по индексу, но не читатель.
Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...