通过一定数量的记录后清除内存

Clear memory after some number of records passed

我在数据库中有几米的记录,需要不时地处理它。但是,此操作会占用我服务器上的所有内存。我正在 运行 使用 sidekiq 执行此操作。因此,当此任务使用所有内存时,我的 rails 应用程序变得非常慢。

总的来说(不包括逻辑)我的代码看起来像

Model.each do |m|
//do some logic code here
end

如何在一定数量的记录(例如 10k 条记录)后让垃圾收集器达到 运行,这样我就不会遇到内存不足的情况。将它分成几块对我有帮助吗?

在处理可能很大的表时,您应该始终使用 find_each

这样,模型将从数据库中检索并逐批加载到内存中(默认大小为 1000,但您可以根据需要自定义)。

请注意,按任意列排序在 find_each 中效果不佳,因为它隐式按 ID 对记录进行排序,因此它有办法按批次获取记录。

您可以使用 GC.start 强制垃圾收集器 运行,但如果您这样做

Model.all.each do |m|
end

那么垃圾收集器无法释放已处理的记录 - 它们仍被 each 正在迭代的数组引用,因此 运行 垃圾收集器显式不会执行任何操作。

而是使用 find_each(或其近亲,find_in_batches)获取记录并分批处理它们(您可以控制批大小 - 我认为默认情况下为 1000)。这样整个结果集永远不会在内存中,并且以前处理的批次不会被任何东西引用,因此可以被处理掉。