Garbage collection and Arrays

Discussion in 'Ruby' started by Aaron Patterson, Jan 12, 2007.

  1. Hi, I seem to be running in to some garbage collection weirdness.
    Hopefully someone will have some insight for me.... My sample script
    seems to leak Strings when I use shift on an Array, but not pop:

    array = []
    10.times { array << "foo" }
    10.times { array.pop } # Change this to shift to see a leak

    o_count = Hash.new(0)
    GC.start
    ObjectSpace.each_object { |o| o_count[o.class] += 1 }

    o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }

    Is this a bug? Or is there something I'm missing? Thanks!

    --Aaron

    --
    Aaron Patterson
    http://tenderlovemaking.com/
    Aaron Patterson, Jan 12, 2007
    #1
    1. Advertising

  2. On 1/12/07, Aaron Patterson <> wrote:
    > Hi, I seem to be running in to some garbage collection weirdness.
    > Hopefully someone will have some insight for me.... My sample script
    > seems to leak Strings when I use shift on an Array, but not pop:


    http://recursive.ca/hutch/index.php?p=361
    Gregory Brown, Jan 12, 2007
    #2
    1. Advertising

  3. On Fri, Jan 12, 2007 at 04:05:55PM +0900, Gregory Brown wrote:
    > On 1/12/07, Aaron Patterson <> wrote:
    > >Hi, I seem to be running in to some garbage collection weirdness.
    > >Hopefully someone will have some insight for me.... My sample script
    > >seems to leak Strings when I use shift on an Array, but not pop:

    >
    > http://recursive.ca/hutch/index.php?p=361
    >


    Thanks!

    --
    Aaron Patterson
    http://tenderlovemaking.com/
    Aaron Patterson, Jan 12, 2007
    #3
  4. Aaron Patterson

    Guest

    On Fri, 12 Jan 2007, Aaron Patterson wrote:

    > Hi, I seem to be running in to some garbage collection weirdness.
    > Hopefully someone will have some insight for me.... My sample script
    > seems to leak Strings when I use shift on an Array, but not pop:
    >
    > array = []
    > 10.times { array << "foo" }
    > 10.times { array.pop } # Change this to shift to see a leak
    >
    > o_count = Hash.new(0)
    > GC.start
    > ObjectSpace.each_object { |o| o_count[o.class] += 1 }
    >
    > o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }
    >
    > Is this a bug? Or is there something I'm missing? Thanks!


    Check the archives of the list for extensive discussion. The upshot is
    that it's a problem with this shift() method.


    Kirk Haines
    , Jan 12, 2007
    #4
  5. Aaron Patterson

    bbiker Guest

    Aaron Patterson wrote:
    > On Fri, Jan 12, 2007 at 04:05:55PM +0900, Gregory Brown wrote:
    > > On 1/12/07, Aaron Patterson <> wrote:
    > > >Hi, I seem to be running in to some garbage collection weirdness.
    > > >Hopefully someone will have some insight for me.... My sample script
    > > >seems to leak Strings when I use shift on an Array, but not pop:

    > >
    > > http://recursive.ca/hutch/index.php?p=361
    > >

    >
    > Thanks!
    >
    > --
    > Aaron Patterson
    > http://tenderlovemaking.com/


    The workaround to eliminate leakage with array.shift works except that
    shift no longer returns the shifted element and instead returns nil

    The following class allows shift to work normally without the leakage
    .... I know it is only a temporary work around until the ruby developers
    get around to fix the c code

    #### Array#shift ###############
    class Array
    alias :eek:rig_shift :shift
    def shift
    return nil if self.empty?
    ret = self[0]
    self[0] = nil
    self.orig_shift
    return ret
    end
    end

    ###### code to show that the leakage has been eliminated
    separator = "---"
    o_count = Hash.new(0)
    GC.start

    ObjectSpace.each_object { |o| o_count[o.class] += 1 }
    o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }
    o_count = nil
    puts separator

    array = []
    10.times { array << "foo" }
    10.times { array.pop } # Change this to shift to see a leak

    o_count = Hash.new(0)
    GC.start
    ObjectSpace.each_object { |o| o_count[o.class] += 1 }
    o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }
    array = nil
    o_count = nil

    puts separator
    array = []
    10.times { array << "foo" }
    10.times { array.shift } # Change this to shift to see a leak

    o_count = Hash.new(0)
    GC.start
    ObjectSpace.each_object { |o| o_count[o.class] += 1 }
    o_count.sort_by { |k,v| -v}.each { |k,v| puts "#{k}: #{v}" }

    __END__

    ####### test results only pertinent data shown
    NEW shift method

    before pop after pop
    before shift after shift
    String: 1746 1764 1764
    Array: 70 71 72

    OLD shift methed -- Class Array commented out
    before pop after pop
    before shift after shift
    String: 1746 1764 1774
    Array: 70 71 72


    ################## code to show that Array#shift behaves as described
    in the ri documentation

    class Array
    alias :eek:rig_shift :shift
    def shift
    return nil if self.empty?
    ret = self[0]
    self[0] = nil
    self.orig_shift
    return ret
    end
    end

    a = (1..5).to_a

    1.upto(10) do |i|
    x = a.shift

    puts "#{i}: \tx: #{x.inspect} \ta: #{a.inspect}"
    end

    __END__


    1: x: 1 a: [2, 3, 4, 5]
    2: x: 2 a: [3, 4, 5]
    3: x: 3 a: [4, 5]
    4: x: 4 a: [5]
    5: x: 5 a: []
    6: x: nil a: []
    7: x: nil a: []
    8: x: nil a: []
    9: x: nil a: []
    10: x: nil a: []
    bbiker, Jan 14, 2007
    #5
    1. Advertising

Want to reply to this thread or ask your own question?

It takes just 2 minutes to sign up (and it's free!). Just click the sign up button to choose a username and then you can ask your own questions on the forum.
Similar Threads
  1. Laser Lu

    Garbage Collection and Manage Code?

    Laser Lu, Jan 26, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    689
    Gaurav Khanna [C# MVP]
    Jan 27, 2004
  2. =?Utf-8?B?RnJhbms=?=

    ASP.NET Session State Server and garbage collection

    =?Utf-8?B?RnJhbms=?=, Jan 29, 2004, in forum: ASP .Net
    Replies:
    5
    Views:
    3,537
    Alvin Bruney [MVP]
    Jan 31, 2004
  3. Replies:
    1
    Views:
    426
    mrstephengross
    Jul 25, 2005
  4. Øyvind Isaksen
    Replies:
    1
    Views:
    927
    Øyvind Isaksen
    May 18, 2007
  5. Philipp
    Replies:
    21
    Views:
    1,093
    Philipp
    Jan 20, 2009
Loading...

Share This Page