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

Optimization 在编写Lucene.Net索引时,内存使用量不断增加,optimization,nlp,lucene.net,information-retrieval,Optimization,Nlp,Lucene.net,Information Retrieval,在谷歌搜索Lucene.Net的使用情况之后,我开始了这个讨论,我没有发现任何真正有用的东西。 问题很简单:我在构建和更新Lucene.Net索引时遇到了一个问题。特别是它的内存使用量一直在增长,即使我将SetRAMBufferSizeMB修改为256,将SetMergeFactor修改为100,将MaxMergeDocs修改为100000。此外,每次使用索引时,我都会小心地使用Close()和Commit()方法 为了使lucene.Net适用于我的数据,我从本教程开始: 对于10^5和10^

在谷歌搜索Lucene.Net的使用情况之后,我开始了这个讨论,我没有发现任何真正有用的东西。 问题很简单:我在构建和更新Lucene.Net索引时遇到了一个问题。特别是它的内存使用量一直在增长,即使我将SetRAMBufferSizeMB修改为256,将SetMergeFactor修改为100,将MaxMergeDocs修改为100000。此外,每次使用索引时,我都会小心地使用Close()和Commit()方法

为了使lucene.Net适用于我的数据,我从本教程开始:

对于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:=具有6GB RAM的12核Xeon工作站。 -Lucene.Net版本:2.9.4g(当前稳定)。 -Lucene.Net目录类型:FSDirectory(索引写入磁盘)


好的,我使用您关于重复使用文档/字段实例的建议测试了代码,但是代码在内存使用方面的性能完全相同。 在这里,我为我在
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.
索引过程维度如下所示:

即使
IndexWriter
利用的
RAM
缓冲区或多或少没有变化,也很容易观察到
RAM
中进程的增长速度(在索引过程的
6%
~1.5GB
)。因此,问题是:是否可以明确限制索引进程大小的
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;

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

Lucene中还有很多其他对象也会使用内存,而和RamBuffer无关


通常,在索引时运行OOM时,首先要尝试的是重用文档/字段实例。如果使用多线程索引,请确保仅在同一线程上重用它们。正因为如此,我才碰巧运行了OOM,当时底层IO速度非常快,.NET垃圾收集器无法跟上创建的所有小对象。

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

Lucene中还有很多其他对象也会使用内存,而和RamBuffer无关


通常,在索引时运行OOM时,首先要尝试的是重用文档/字段实例。如果使用多线程索引,请确保仅在同一线程上重用它们。正因为如此,我才碰巧运行OOM,当时底层IO运行得很快,.NET垃圾收集器无法跟上创建的所有小对象。

最后,我发现了错误。它包含在利用Luca Gentili贡献构建的意大利语分析器(意大利语分析器)中(http://snowball.tartarus.org/algorithms/italian/stemmer.html). 实际上,在Italianalyzer类中,包含停止字的文件打开了好几次,每次使用后都没有关闭。这就是我的OOM问题的原因。
Lucene.Net解决这个bug的方法是光速构建索引和搜索。

最后,我找到了这个bug。它包含在利用Luca Gentili贡献构建的意大利语分析器(意大利语分析器)中(http://snowball.tartarus.org/algorithms/italian/stemmer.html). 实际上,在Italianalyzer类中,包含停止字的文件打开了好几次,每次使用后都没有关闭。这就是我的OOM问题的原因。 解决这个错误Lucene.Net是光速建立索引和搜索