Indexing Lucene.Net 2.9.2:添加多个文档时出现OOM异常

Indexing Lucene.Net 2.9.2:添加多个文档时出现OOM异常,indexing,lucene.net,out-of-memory,Indexing,Lucene.net,Out Of Memory,我正在尝试使用Lucene.NET 2.9.2为大约10.000.000个文档编制索引。这些文档(不同长度的论坛帖子)从MSSQL数据库中以10.000的大容量获取,然后传递到我的Lucene.NET包装类LuceneCorpus: public static void IndexPosts(LuceneCorpus luceneCorpus, IPostsRepository postsRepository, int chunkSize) { // omitted: this whol

我正在尝试使用Lucene.NET 2.9.2为大约10.000.000个文档编制索引。这些文档(不同长度的论坛帖子)从MSSQL数据库中以10.000的大容量获取,然后传递到我的Lucene.NET包装类LuceneCorpus:

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();
    }
}
公共类LuceneCorpus
{
专用分析仪(u分析仪),;
私有目录_indexDir;
私人索引编写器;
公共LuceneCorpus(目录信息索引目录)
{
_indexDirectory=FSDirectory.Open(indexDirectory);
_analyzer=新标准分析仪(版本:LUCENE_29);
_writer=new IndexWriter(_indexDir,_analyzer,true,IndexWriter.MaxFieldLength.UNLIMITED);
_作者:SetRAMBufferSizeMB(128);
}
公共无效的AddPosts(IEnumerable posts)
{
列表单据=新建列表();
foreach(var post in post)
{
var doc=新文档();
新增单据(新增字段(“SimplifiedBody”,post.SimplifiedBody,Field.Store.NO,Field.Index.analysisted));
_writer.AddDocument(doc);
}
_writer.Commit();
}
公共索引()
{
_writer.Optimize();
}
}
现在,我的问题是,内存消耗一直在不断地被填满,直到我在IndexPosts方法中索引了大约700.000个文档之后,最终出现内存不足异常

据我所知,索引编写器应该在达到RAMBufferSize(128 MB)或调用Commit()时刷新。事实上,作者肯定会刷新,甚至会跟踪刷新,但内存仍在不断填满。作者是否以某种方式保留了对文档的引用,以便它们不会被垃圾收集,或者我在这里遗漏了什么

提前谢谢

Edit:我还尝试在AddPosts方法的范围内而不是在类范围内初始化writer、analyzer和indexDir,但这也不能防止OOM异常

我读到建议使用单个IndexWriter而不是 为每批文档打开和关闭一个新文档

一般来说,这可能是正确的,但您的特殊情况似乎需要另一种方法。您应该尝试每批使用一个writer。您的大内存需求迫使您使用效率低于最佳的解决方案。用内存换取速度,反之亦然——这很常见

我读到建议使用单个IndexWriter而不是 为每批文档打开和关闭一个新文档


一般来说,这可能是正确的,但您的特殊情况似乎需要另一种方法。您应该尝试每批使用一个writer。您的大内存需求迫使您使用效率低于最佳的解决方案。用内存换取速度,反之亦然——这很常见。

试试最新和最棒的。它有一些内存泄漏修复


试试最新最棒的。它有一些内存泄漏修复


显然,Lucene没有导致内存泄漏,但我的PostsRepository的数据上下文是。我通过为每个“Take”迭代使用一个临时的非跟踪DC来解决这个问题


对不起,谢谢你

显然Lucene并没有导致内存泄漏,但我的PostsRepository的DataContext是。我通过为每个“Take”迭代使用一个临时的非跟踪DC来解决这个问题


对不起,谢谢你

一般来说,这很好,但即使我使用每批编写器的方法,问题也会出现。我用不同的批处理大小(500、1000或10000个文档)尝试了这种方法,但内存仍在不断地填满(!),直到我的内存用完。仅供参考:既然Lucene无关内存泄漏已经修复,我甚至可以使用单编写器方法!一般来说,这很好,但即使我使用每批编写器的方法,问题也会出现。我用不同的批处理大小(500、1000或10000个文档)尝试了这种方法,但内存仍在不断地填满(!),直到我的内存用完。仅供参考:既然Lucene无关内存泄漏已经修复,我甚至可以使用单编写器方法!