我有一个全天更新的实时Lucene索引。当索引的几个连续批次更新通过时,我希望这些更新可以尽快进行搜索。因此,我必须重新创建IndexSearcher。
问题是IndexSearcher可以占用大约100mb的内存,当很多更新通过时,它可以相对经常重建,我注意到.Net垃圾收集器似乎很慢清理对旧的IndexSearcher对象。这导致进程的内存使用量失控,因为收集器似乎比重新创建时更慢地从旧的IndexSearchers中释放内存。
我发现通过将行划分为禁忌区并调用GC.Collect()
来缓解此问题,这会立即释放内存。性能影响似乎并不明显,但由于我正在做一些许多建议反对的事情,我很好奇是否有其他人拥有创建和发布对象的经验比垃圾收集器正在清理它们更快。如果有人对Lucene IndexSearcher有这个问题,我会特别感兴趣。
我应该注意到,IndexSearcher正在高峰时间每10-20秒重建一次。
答案 0 :(得分:3)
如果您刚刚释放了大量内存,我认为调用GC.Collect
是可以接受的,现在可以而且应该释放内存以减少内存压力。 GC不知道这个内存现在可用,直到它再次运行,你不知道什么时候会有。
在你的情况下,你说“它可以相对经常重建”。如果是这样,重新创建它时调用GC.Collect
听起来是合理的。
答案 1 :(得分:2)
您是否尝试过为服务器配置垃圾回收?我认为它的不同之处在于GC在另一个主题上:
Should we use "workstation" garbage collection or "server" garbage collection?
至于“比清理更快”,如果内存可用,则系统会将其授予您的进程。随着内存的增长,垃圾收集器将在各个连接处收集,但它不会停止分配以保持一定的内存压力 - 操作系统管理压力。
不幸的是我没有Lucene的直接经验,所以我的回答只是垃圾收集。