Garbarge Collection in Ruby with Circular Object References
garbage-collection, ruby
Solution
The GC in Ruby works essentially like so:
Mark all global objects as live.
Sweep through objects, garbage collect unless a parent is live.
So, in the case of a circular reference, A holding onto B holding onto A would get GC'd because neither is being held by a live object.
Per the comments, something is necessarily holding onto the object somewhere... Or maybe Mass is catching RangeError or something...
>> a = {}
=> {}
>> a[:a] = a
=> {:a=>{...}}
>> a.object_id
=> 2269556540
>> a = nil
=> nil
>> GC.start
=> nil
>> ObjectSpace._id2ref(2269556540)
RangeError: 0x8746af3c is recycled object
from (irb):17:in `_id2ref'
from (irb):17
Problem
I'm having an issue with garbage collection in Ruby where an object that I think should be garbage collection is not being garbage collected. ``` require 'ruby-mass' def find_dependencies(_object_id,_mapped = {}) mapped = _mapped points_to_object = Mass.references(Mass[_object_id]) ids = points_to_object.keys.map{|x| /\#(\d*)/.match(x).captures.first.to_i} mapped[_object_id] = ids unmapped = ids - mapped.keys unmapped.each do |x| new_deps = find_dependencies(x,mapped) mapped.merge(new_deps) end mapped end ``` Do some stuff that makes the objects, and find the relevant object ID. `GC.start`, then: ``` > find_dependencies(144789180) => {144789180=>[61895480, 144786340, 147807540], 61895480=>[144789180], 144786340=>[144789180], 147807540=>[144789180]} ``` It looks like there is a circular reference pattern here, but it is all completely contained in these four objects, so the Mark-and-Sweep collector should find them and remove them. So, either there is a bug in my find_dependencies_function, the Mass gem, or Ruby's garbage collector. How do I narrow this down to find out what the problem is and solve this memory leak?