2011-08-28 14 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 (128MB)에 도달하거나 Commit()이 호출되면 플러시해야합니다. 사실, 작가는 분명히 플러시를하고 심지어 플러시를 추적하지만 메모리는 계속 채워집니다. 작가가 문서에 대한 참조를 어떻게 든 지키고있어 가비지 수집이되지 않거나 여기에 무엇이 누락되어 있습니까?

미리 감사드립니다.

편집 : 또한 클래스 작성기 대신 AddPosts 메서드의 범위에서 작성기, 분석기 및 indexDir을 초기화 해 보았지만 OOM 예외를 방지하지는 못했습니다.

답변

0

은 분명히 루씬은 메모리 누수의 원인이되지하지만 내 PostsRepository의 DataContext를했다. 각 "테이크 (Take)"반복에 대해 임시 비 추적 DC를 사용하여 문제를 해결했습니다.

죄송합니다. 어쨌든 감사합니다.

0

나는 각 문서의 대용량에 대해 새로 열거 나 닫는 대신 하나의 IndexWriter를 사용하는 것이 좋습니다.

일반적으로 사실 일 수 있지만 특수한 경우에는 다른 접근 방법이 필요합니다. 배치 당 작가를 시험해야합니다. 대용량 메모리 요구 사항으로 인해 최적이 아닌 효율성 솔루션을 사용해야합니다. 스피드와 비자의 거래 메모리 - 일반적입니다.

+0

일반적으로 문제가되지 않지만 필자가 일괄 처리 방식을 사용하는 경우에도 문제가 발생합니다. 다른 배치 크기 (500, 1000 또는 10000 문서)로 시도했지만 메모리가 부족해질 때까지 메모리가 계속해서 채워집니다 (!). – Shackles

+0

참고 : Lucene과 관련없는 메모리 누출 문제가 수정되었으므로 이제는 단일 작성자 방식을 사용할 수도 있습니다. – Shackles

관련 문제