31

我有大约六个 Sidekiq 工作人员执行JSON 爬行。根据端点的数据集大小,它们在 1 分钟到 4 小时之间完成。尤其是观看耗时 4 小时的长篇,我发现随着时间的推移,内存会略有增加。

这不是问题,直到我想再次安排相同的工人作业。内存不会被释放并堆积起来,直到我遇到 Linux OOM Killer,它摆脱了我的 Sidekiq 进程。

内存泄漏?我观察了 ObjectSpace 中不同对象的数量:

ObjectSpace.each_object.inject(Hash.new(0)) { |count, o| count[o.class] += 1 }

那里并没有真正增加,散列、数组等的集合保持不变,短暂的增加被垃圾收集器扫除,并gc.stat[:count]告诉我垃圾收集器也在工作。

即使在工作人员完成后,例如我记录了[Done]并且没有工作人员再忙,内存也不会被释放。原因是什么?我可以对此做些什么吗?写一个终结器?

当前唯一的解决方案:重新启动 Sidekiq 进程。

我在 Ruby 2.0.0 上并使用 Ruby MRI。


对于 JSON 解析,我使用Yajl,因此是 C 绑定。我需要它,因为它似乎是唯一能够正确实现流式读写的快速 JSON 解析器。

4

1 回答 1

13

编写 Sidekiq 的Mike Perham在这里解决了这个问题:http: //www.mikeperham.com/2009/05/25/memory-hungry-ruby-daemons/

tl;dr 版本: MRI 不会返还内存,您最多只能控制堆,为此建议使用Ruby 企业版

不知道这有什么帮助,但情况就是这样——直接从马的嘴里说出来。

于 2013-12-06T12:50:36.443 回答