在RoR脚本中减少ruby的内存使用量

时间:2013-02-14 15:15:38

标签: ruby ruby-on-rails-3 memory-management

我有一个RoR应用程序和一个cron rake-task,类似于:

Model.all.each do |m|
  if m < some_condition
    m.do_something
    m.save
  end
end

Model有1 000 000条记录(20万条条件可接受)。有没有办法改善任务内存的使用?它需要几千兆字节的内存,并且Ruby进程在生产时被服务器杀死。我的DB是PostgreSQL。

3 个答案:

答案 0 :(得分:2)

您应该使用#find_each#find_in_batches等方法。这些将一次只加载一小部分记录。看看ActiveRecord::Batches

答案 1 :(得分:2)

我建议使用find_each,它会分批生成您的对象。

另外,如果可能的话,在sql中应用你在循环中的条件,因此ActiveRecord不必实例化你不使用的对象(因此使用内存):

Model.find_each(:conditions => {:my => :condition}).each do |m|
  # do something
end

答案 2 :(得分:1)

您可以尝试以下方法:

  def with_gc(enum)
    count = enum.count
    limit = 100
    (0..count).select{|i| i % limit == 0}.each do |index|
      new_count = enum.count
      raise "query depends on updated param. Expected count #{count}, got #{new_count}" if count != new_count
      enum.skip(index).limit(limit).each do |record|
        yield record
      end
      GC.start
    end
  end

你可以像这样使用它:

with_gc(Model.all) do |m|
  if m < some_condition
    m.do_something
    m.save
  end
end