Ruby Memory Management

后端 未结 5 1867
遥遥无期
遥遥无期 2020-12-23 21:32

I have been using Ruby for a while now and I find, for bigger projects, it can take up a fair amount of memory. What are some best practices for reducing memory usage in Ru

5条回答
  •  予麋鹿
    予麋鹿 (楼主)
    2020-12-23 22:24

    When working with huge arrays of ActiveRecord objects be very careful... When processing those objects in a loop if on each iteration you are loading their related objects using ActiveRecord's has_many, belongs_to, etc. - the memory usage grows a lot because each object that belongs to an array grows...

    The following technique helped us a lot (simplified example):

    students.each do |student|
      cloned_student = student.clone
      ...
      cloned_student.books.detect {...}
      ca_teachers = cloned_student.teachers.detect {|teacher| teacher.address.state == 'CA'}
      ca_teachers.blah_blah
      ...
      # Not sure if the following is necessary, but we have it just in case...
      cloned_student = nil
    end
    

    In the code above "cloned_student" is the object that grows, but since it is "nullified" at the end of each iteration this is not a problem for huge array of students. If we didn't do "clone", the loop variable "student" would have grown, but since it belongs to an array - the memory used by it is never released as long as array object exists.

    Different approach works too:

    students.each do |student|
      loop_student = Student.find(student.id) # just re-find the record into local variable.
      ...
      loop_student.books.detect {...}
      ca_teachers = loop_student.teachers.detect {|teacher| teacher.address.state == 'CA'}
      ca_teachers.blah_blah
      ...
    end
    

    In our production environment we had a background process that failed to finish once because 8Gb of RAM wasn't enough for it. After this small change it uses less than 1Gb to process the same amount of data...

提交回复
热议问题