在编写Lucene.Net索引时,内存使用量不断增长

时间:2012-08-24 14:38:04

标签: optimization nlp lucene.net information-retrieval

我打开这个讨论,因为谷歌搜索Lucene.Net用法我没有找到任何真正有用的东西。 问题很简单:我在构建和更新Lucene.Net索引时遇到了问题。特别是它的内存使用量不断增长,即使我将SetRAMBufferSizeMB修复为256,将SetMergeFactor修复为100,将SetMaxMergeDocs修复为100000.此外,每次使用索引时,我都会小心使用Close()和Commit()方法。

为了让lucene.Net适用于我的数据,我从本教程开始:http://www.lucenetutorial.com/lucene-in-5-minutes.html

似乎对于10 ^ 5和10 ^ 6个文件,需要1.8GB的ram。因此,如果实际的RAM使用率是7倍以上,为什么要设置SetRAMBufferSizeMB参数?有没有人真的知道如何限制内存使用?

此外,我观察到要处理10 ^ 5或10 ^ 6文档,有必要为x64平台编译Lucene.Net。实际上,如果我编译x86平台的代码,索引崩溃会系统地触及1.2GB的RAM。 有没有人能够使用更少的RAM索引相同数量的文档(甚至更多)?在哪些硬件和软件设置?我的环境配置如下: - os:= win7 32/64位。 - sw:= .Net framework 4.0 - hw:= 12核Xeon工作站,内存为6GB。 - Lucene.Net rel。:2.9.4g(当前稳定)。 - Lucene.Net目录类型:FSDirectory(索引写入磁盘)。


好的,我使用你对重复使用Document / Fields实例的建议来测试代码,但代码在内存使用方面的表现完全相同。 在这里,我为1000000文档的索引过程中跟踪的一些参数发布了一些调试行。

DEBUG - BuildIndex – IndexWriter - RamSizeInBytes 424960B; index process dimension 1164328960B.  4% of the indexing process.
DEBUG - BuildIndex – IndexWriter - RamSizeInBytes 457728B; index process dimension 1282666496B.  5% of the indexing process.
DEBUG - BuildIndex – IndexWriter - RamSizeInBytes 457728B; index process dimension 1477861376B.  6% of the indexing process.

索引流程维度如下:

即使RAM缓冲区利用~1.5GB缓冲区,也很容易观察到6%RAM在索引进程的IndexWriter)进程的增长速度{1}}或多或少没有变化。因此,问题是:是否可以明确限制索引进程大小的RAM使用?我不关心在搜索阶段性能是否下降以及我是否需要等待一段时间来获得完整的索引,但我需要确保索引过程没有达到OOM或堆栈溢出错误索引大量文档。如果无法限制内存使用量,我怎么能这样做?

为了完整起见,我发布了用于调试的代码:

// get the current process
Process currentProcess = System.Diagnostics.Process.GetCurrentProcess();
// get the physical mem usage of the index writer 
long totalBytesOfIndex = writer.RamSizeInBytes();
// get the physical mem usage
long totalBytesOfMemoryUsed = currentProcess.WorkingSet64;

2 个答案:

答案 0 :(得分:2)

最后,我发现了这个错误。它包含在ItalianAnalyzer(意大利语语言的分析者)中,该语言利用Luca Gentili的贡献(http://snowball.tartarus.org/algorithms/italian/stemmer.html)。确实在ItalianAnalyzer类中,包含停用词的文件已经打开了几次,每次使用后它都没有关闭。这就是OOM问题的原因。 解决这个问题,Lucene.Net可以轻松地构建索引和搜索。

答案 1 :(得分:0)

SetRAMBufferSizeMB只是确定何时将IndexWriter刷新到磁盘的方法之一。当XXX MB写入内存并准备刷新到磁盘时,它将刷新段数据。

Lucene中有很多其他对象也会使用内存,与RamBuffer无关。

通常,在索引时运行OOM时要尝试的第一件事是重新使用Document / Fields实例。如果多线程索引,请确保只在同一个线程上重用它们。因此,当我运行OOM时,底层的IO速度非常快,.NET垃圾收集器无法跟上所有创建的小对象。