2011-08-28 76 views
1

我想用Lucene.NET 2.9.2來索引大約10.000.000個文檔。這些文件(長度不同的論壇帖子)是從MSSQL數據庫採取10.000散貨,然後傳遞給我的Lucene.NET包裝類稱爲LuceneCorpus:Lucene.Net 2.9.2:添加多個文檔時出現OOM異常

public static void IndexPosts(LuceneCorpus luceneCorpus, IPostsRepository postsRepository, int chunkSize) 
{ 
    // omitted: this whole method is executed in a background worker to enable GUI feedback 
    // chunkSize is 10.000 
    int count = 0; 
    // totalSteps is ~10.000.000 
    int totalSteps = postsRepository.All.Count(); 
    while (true) 
    { 
     var posts = postsRepository.All.Skip(count).Take(chunkSize).ToList(); 
     if (posts.Count == 0) 
      break; 
     luceneCorpus.AddPosts(posts); 
     count += posts.Count;     
    } 
    luceneCorpus.OptimizeIndex(); 
} 

我讀了推薦使用單一的IndexWriter而不是爲每一批文件打開和關閉一個新文件。因此,我LuceneCorpus類看起來是這樣的:

public class LuceneCorpus 
{ 
    private Analyzer _analyzer; 
    private Directory _indexDir; 
    private IndexWriter _writer; 

    public LuceneCorpus(DirectoryInfo indexDirectory) 
    { 
     _indexDir = FSDirectory.Open(indexDirectory); 
     _analyzer = new StandardAnalyzer(Version.LUCENE_29); 
     _writer = new IndexWriter(_indexDir, _analyzer, true, IndexWriter.MaxFieldLength.UNLIMITED); 
     _writer.SetRAMBufferSizeMB(128); 
    } 

    public void AddPosts(IEnumerable<Post> posts) 
    { 
     List<Document> docs = new List<Document>(); 
     foreach (var post in posts) 
     { 
      var doc = new Document(); 
      doc.Add(new Field("SimplifiedBody", post.SimplifiedBody, Field.Store.NO, Field.Index.ANALYZED)); 
      _writer.AddDocument(doc); 
     } 
     _writer.Commit(); 
    } 

    public void OptimizeIndex() 
    { 
     _writer.Optimize(); 
    } 
} 

現在,我的問題是,內存消耗不斷在IndexPosts方法填補,直到我終於到達索引之後的內存不足的異常約700.000文件的某處。

據我所知,索引寫入器應該在達到RAMBufferSize(128 MB)或調用Commit()時進行刷新。事實上,作家肯定會沖洗甚至跟蹤沖洗,但記憶仍在不斷填滿。作者是否保持對文件的引用,以便它們不被垃圾收集或我在這裏錯過了什麼?

在此先感謝!

編輯:我也試着在AddPosts方法的範圍內初始化writer,analyzer和indexDir,而不是class-wide,但是也不能阻止OOM異常。

回答

0

顯然Lucene的未造成內存泄漏,但我PostsRepository的DataContext的是。我通過對每個「Take」迭代使用臨時非跟蹤DC來解決這個問題。

對不起,謝謝反正!

0

我讀到,建議使用單個IndexWriter而不是 打開和關閉每個批量文檔的新文件。

這可能是正確的,但你的特殊情況似乎需要另一種方法。你應該每批試一次作家。您的大內存需求迫使您使用效率低於最佳的解決方案。商業記憶的速度和反之亦然 - 這很常見。

+0

這將是一般的罰款,但即使我使用批處理作家的方法出現問題。我嘗試過使用不同的批量(500,1000或10000個文檔),但內存仍然不斷填滿(!),直到內存不足。 – Shackles

+0

供參考:現在Lucene無關的內存泄漏已經修復,我甚至可以使用單一的寫入器方法! – Shackles

相關問題