1

Is it possible to remove objects from an array/hash which is only referenced from this array/hash?

Example of what I am looking for:

some_array.reject!{|elm| ObjectSpace.only_one_reference_to?(elm)}

I am making a script which seem to be growing quickly in the ram. The reason why is is a long-living array which keeps obsolete objects around event though it does not need to.

The problem is essentially this:

@@long_living_array = []
class Foo
    def initialize
        @@long_living_array << self
    end
end

a = Foo.new()
b = Foo.new()
a = nil
#Here is the problem, a sticks around in @@long_living_array, even though it does not really need to be there.

Thus, my real task is to iterate over the @@long_living_array and remove any objects which is only referenced from this array. (And yes, I do need the array.)


I believe it could be solved if I was able to find all references to an object, and then remove the object if the reference in the array is the only one. Thus I have been looking for something along the lines of

a = Foo.new
all_references_to_a = ObjectSpace.get_all_references(a)

I have found this article which seems to do something similar, but it is a patch to Ruby itself (some C files) so it is not possible for me to use.

1 Answer 1

2

Instead of storing the object itself, you could store a WeakRef. It allows the referenced object to be garbage-collected:

require 'weakref'

@@long_living_array = []

class Foo
  def initialize
    @@long_living_array << WeakRef.new(self)
  end
end

a = Foo.new
b = Foo.new
@@long_living_array.count
#=> 2

a = nil                                       # reassign 'a'
GC.start                                      # start the garbage collector
@@long_living_array.keep_if(&:weakref_alive?) # remove GC'ed objects

@@long_living_array.count
#=> 1
Sign up to request clarification or add additional context in comments.

2 Comments

Nice usecase of weakref.
Cool! I will try this out as soon as I can!

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.