我正在尝试使用Lucene.NET 2.9.2索引大约10.000.000个文档。这些文档(不同长度的论坛帖子)从MSSQL数据库中以10.000的大小获取,然后传递给名为LuceneCorpus的Lucene.NET包装类:
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而不是为每个文档大小打开和关闭一个新的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,而不是在类范围内,但这也不会阻止OOM异常。
答案 0 :(得分:1)
尝试最新且最棒的。它有一些内存泄漏修复。
https://svn.apache.org/repos/asf/incubator/lucene.net/branches/Lucene.Net_2_9_4g/src/
答案 1 :(得分:0)
我读过建议使用单个IndexWriter而不是 为每批文件打开和关闭一个新文件。
总的来说这可能是真的,但是你的特殊情况似乎需要另一种方法。你应该每批尝试一个作家。您的大内存需求迫使您使用不太理想的效率解决方案。交易记忆的速度和反之亦然 - 这很常见。
答案 2 :(得分:0)
显然Lucene没有导致内存泄漏,但我的PostsRepository的DataContext是。我通过为每个“Take”迭代使用临时非跟踪DC来解决它。
对不起,谢谢!