2

自从谷歌搜索关于 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 使用量是 7 倍以上,为什么还要设置 SetRAMBufferSizeMB 参数?有人真的知道如何限制内存使用吗?

此外,我观察到要处理 10^5 或 10^6 文档,必须为 x64 平台编译 Lucene.Net。事实上,如果我为 x86 平台编译代码,索引崩溃会系统地触及 1.2GB 的 RAM。是否有人能够使用更少的 RAM 索引相同数量(甚至更多)的文档?在哪个硬件和软件设置中?我的环境配置如下: - os := win7 32/64 bits。- sw := .Net framework 4.0 - hw := 具有 6GB RAM 的 12 核 Xeon 工作站。- 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%RAMIndexWriterRAMOOM

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

// 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;
4

2 回答 2

4

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

于 2012-09-07T07:44:35.307 回答
0

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

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

通常,在编制索引时运行 OOM 时首先要尝试的是重用 Document/Fields 实例。如果您使用多线程索引,请确保仅在同一线程上重用它们。因此,当底层 IO 飞速发展而 .NET 垃圾收集器无法跟上所有创建的小对象时,我碰巧运行了 OOM。

于 2012-08-25T02:16:51.923 回答