The Artima Developer Community
Sponsored Link

Ruby Buzz Forum
Stuffing Your Hand Down the Disposal

0 replies on 1 page.

Welcome Guest
  Sign In

Go back to the topic listing  Back to Topic List Click to reply to this topic  Reply to this Topic Click to search messages in this forum  Search Forum Click for a threaded view of the topic  Threaded View   
Previous Topic   Next Topic
Flat View: This topic has 0 replies on 1 page
Red Handed

Posts: 1158
Nickname: redhanded
Registered: Dec, 2004

Red Handed is a Ruby-focused group blog.
Stuffing Your Hand Down the Disposal Posted: Jul 7, 2005 4:10 PM
Reply to this message Reply

This post originated from an RSS feed registered with Ruby Buzz by Red Handed.
Original Post: Stuffing Your Hand Down the Disposal
Feed Title: RedHanded
Feed URL: http://redhanded.hobix.com/index.xml
Feed Description: sneaking Ruby through the system
Latest Ruby Buzz Posts
Latest Ruby Buzz Posts by Red Handed
Latest Posts From RedHanded

Advertisement

Since we have our heads tilted in the direction of ruby+gc, Eustáquio “TaQ” Rangel posted concerns about Ruby’s garbage collector yesterday on Ruby-Talk which led to an interesting bit of code from Yohanes Santoso for watching the garbage collector slurp up variables gone from scope.

Specifically this code which creates a bunch of objects and watches them fade from existence.

 class CustObj
   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 CustObj's with ObjectSpace\n" 
   print "#{ObjectSpace.each_object(CustObj) {|v| puts v}}" \
         " objects found\n\n" 
 end

 begin        # start a new scope so we can exit it later
   c1 = CustObj.new(1,CustObj.new(2,CustObj.new(3)))
   c4 = CustObj.new(4,CustObj.new(5))
   c6 = CustObj.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 "### Exited the scope" 
 list

 GC.start                        # here I want c1 disappears

 puts "### After gc, outside of declaring scope" 
 list

Here’s a great script for understanding how the collector works and how important scope is to the collector. The important variable to watch is Object #1. Notice how, even after its set to nil, its object is still around because it is referenced by Object #3. And it’s still around after the scope is closed. But once the scope is closed and the GC is manually run, Object #1 disappears.

The point of this illustration isn’t to encourage you to run GC manually. It’s to encourage you to use scope to control the variables you’re hanging on to. Even if it means enclosing some stuff in begin..end.

Here’s a little watcher class, based on the above that you can use to monitor the presence of objects:

 class GCWatcher
   def initialize; @objs = []; end
   def watch( obj )
     @objs << [obj.object_id, obj.inspect]
     obj
   end
   def list
     puts "** objects watched by GcWatcher **" 
     @objs.each do |obj_id, obj_inspect|
       if ( ObjectSpace._id2ref( obj_id ) rescue nil )
         puts "#{ obj_inspect } is still around." 
       else
         puts "#{ obj_inspect } is collected." 
       end
     end
     puts "** #{ @objs.length } objects watched **" 
     puts
   end
 end

Create a GCWatcher object and fill it with references using the watch method. The object will only keep track of object IDs, so it keeps no reference to the actual objects. See a complete sample here. (Inspired by ruby-talk:147351.)

Read: Stuffing Your Hand Down the Disposal

Topic: Getting Ready for OSCON 2005 Previous Topic   Next Topic Topic: Messaging on the Q.T.

Sponsored Links



Google
  Web Artima.com   

Copyright © 1996-2019 Artima, Inc. All Rights Reserved. - Privacy Policy - Terms of Use