【问题标题】:How to use RAMDirectory and avoid OutOfMemoryException if the object size exceeds 2GB如果对象大小超过 2GB,如何使用 RAMDirectory 并避免 OutOfMemoryException
【发布时间】:2011-12-05 20:41:24
【问题描述】:

我一直在使用 RAMDirectory 将整个索引放入内存以提高性能,它运行良好,直到我的索引不断增长。现在我收到OutOfMemoryException。虽然我在磁盘上的索引为 1.24GB,但我怀疑 RAMDirectory 对象的对象大小最终超过了 .NET 2GB 对象大小限制,因此引发了异常。另一个原因可能是虚拟地址空间过于碎片化,无法为我的对象找到足够大的洞。

我很想继续使用RAMDirectory。如何在避免OutOfMemoryException 的同时做到这一点?

还请注意,当我编写索引时,我会调用IndexWriter.Optimize,因此整个索引都在一个大文件中。

【问题讨论】:

  • 我认为您会看到使用 RAMDirectory 进行搜索的速度提升很小。我会在没有它的情况下尝试它,我敢打赌,一旦你加热索引,你会发现性能相当。
  • 谢谢!加热索引需要什么?
  • 切换到 64 位操作系统。
  • 感谢@Hans,我使用的是 64 位操作系统
  • 这不可能。您是否将主 EXE 项目的 Platform target 属性设置为 AnyCPU?

标签: c# lucene lucene.net out-of-memory ramdirectory


【解决方案1】:

我能想到的继续使用RAMDirectory 的唯一方法是将其拆分为几个较小的索引并使用MultiSearcher

这样您就可以避免 .NET 2GB 对象大小限制,请注意,即使在 64 位上,单个对象仍然有 2GB 的大小限制,RamDirectory 在内部保存一个字节数组来表示索引,这可能是如果它太大,是什么让它爆炸。

以我的拙见,您可能应该考虑使用具有大索引的 FSDirectory,它的速度通常对于大多数应用程序来说已经足够好了。

【讨论】:

  • 谢谢!似乎使用内存对象获得的性能将被使用 MultiSearcher 的性能损失所抵消。
  • 当您重新打开搜索器时只需运行几个典型查询,以便它可以建立缓存。我这样做的方式是,当我重新打开搜索器时,我保持旧搜索器打开以继续提供查询并开始预热新搜索器。当它预热时,我用新的替换旧的(基本上是改变一个变量的值)并在交换完成后关闭旧的搜索器。
  • 非常感谢!似乎正确的答案是使用 FSDirectory,因为如果索引大小达到 2G,则没有使用 RAMDirectory 的好方法。
猜你喜欢
  • 1970-01-01
  • 2013-10-23
  • 1970-01-01
  • 1970-01-01
  • 2017-07-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多