From: Yohanes Santoso Date: 2005-07-07T06:57:47+09:00 Subject: Re: Collecting garbage "Eustaquio Rangel de Oliveira Jr." writes: > My question is, when assigning nil to c1, it should not invalidate all > the inner objects and becomes available for garbage collection? > On the example above, I assigned nil to c1 and c4.next (5), and after > the GC.start I don't have 5, but still have c1 (same id), 2 and 3. On > that case, that memory will never be sweeped (free)? Because seems > that I'll always have a Object with id -604874856 and will not have a > way to refer to it later, for use or free the allocated memory for it. Ruby's GC is lazy and conservative. Lazy meaning, it does not exhaustively try to do path-finding on each object because for some objects, path-finding is an expensive process. Conservative meaning, if it is not doing a path-finding on an object, that object is not freed. Hate it or love it. It has both advantages and disadvantages. You have just shown a disadvantage. But it can be mitigated by exiting the scope which should make path-finding to those objects cheaper. class CustomObject attr_accessor :val, :next def initialize(v,n=nil) @val = v @next = n end def to_s "Object #{@val} (#{self.object_id}) points to #{@next.nil? ? 'nothing' : @next.val} (#{@next.nil? ? '':@next.object_id})" end end def list print "Listing all CustomObject's with ObjectSpace\n" print "#{ObjectSpace.each_object(CustomObject) {|v| puts v}} objects found\n\n" end begin # start a new scope so we can exit it later c1 = CustomObject.new(1,CustomObject.new(2,CustomObject.new(3))) c4 = CustomObject.new(4,CustomObject.new(5)) c6 = CustomObject.new(6) c1.next.next.next = c1 # comment this and check again puts "### Initial" list c1 = nil c4.next = nil GC.start puts "### After gc, but still within declaring scope" list end puts "### Exitted the scope" list GC.start # here I want c1 disappears puts "### After gc, outside of declaring scope" list Output: ### Initial Listing all CustomObject's with ObjectSpace Object 6 (-604561942) points to nothing () Object 4 (-604561932) points to 5 (-604561922) Object 5 (-604561922) points to nothing () Object 1 (-604561912) points to 2 (-604561902) Object 2 (-604561902) points to 3 (-604561892) Object 3 (-604561892) points to 1 (-604561912) 6 objects found ### After gc, but still within declaring scope Listing all CustomObject's with ObjectSpace Object 6 (-604561942) points to nothing () Object 4 (-604561932) points to nothing () Object 1 (-604561912) points to 2 (-604561902) Object 2 (-604561902) points to 3 (-604561892) Object 3 (-604561892) points to 1 (-604561912) 5 objects found ### Exitted the scope Listing all CustomObject's with ObjectSpace Object 6 (-604561942) points to nothing () Object 4 (-604561932) points to nothing () Object 1 (-604561912) points to 2 (-604561902) Object 2 (-604561902) points to 3 (-604561892) Object 3 (-604561892) points to 1 (-604561912) 5 objects found ### After gc, outside of declaring scope Listing all CustomObject's with ObjectSpace Object 6 (-604561942) points to nothing () Object 4 (-604561932) points to nothing () 2 objects found