T
Tim Bates
Hi all,
I'm trying to build a caching mechanism into a library I'm writing. I
want to do it using weakrefs. It will look something like this:
require 'weakref'
class Cache
class << self
@cache_hash = {}
def insert(obj, id)
@cache_hash[id] = WeakRef.new(obj)
end
def retrieve(id)
o = @cache_hash[id]
# If this object hasn't been GC'd yet
if o.weakref_alive?
# Return a strong ref to it.
o.__getobj__
else
# Regenerate and return object
# o = MyClass.fetch(id)
insert(o, id)
o
end
end
end
end
Unfortunately, this doesn't work. The idea is that the cache always
returns strong-refs, so that the user doesn't have to worry about them
getting garbage-collected - to the user, they're just ordinary objects.
However, once they go outside the user's scope, the only reference to
them left is the weakref in the cache, and they can be garbage
collected. Then, if the user requests it again, it can be returned if
it's not GC'd yet, or regenerated and returned if it has.
It seems, though, that the WeakRef implementation is such that if you
refer to an object other than via its weakref, the weakref-ness is
destroyed and the object never gets GC'd. Can anyone explain why and/or
offer a way around this?
Tim Bates
I'm trying to build a caching mechanism into a library I'm writing. I
want to do it using weakrefs. It will look something like this:
require 'weakref'
class Cache
class << self
@cache_hash = {}
def insert(obj, id)
@cache_hash[id] = WeakRef.new(obj)
end
def retrieve(id)
o = @cache_hash[id]
# If this object hasn't been GC'd yet
if o.weakref_alive?
# Return a strong ref to it.
o.__getobj__
else
# Regenerate and return object
# o = MyClass.fetch(id)
insert(o, id)
o
end
end
end
end
Unfortunately, this doesn't work. The idea is that the cache always
returns strong-refs, so that the user doesn't have to worry about them
getting garbage-collected - to the user, they're just ordinary objects.
However, once they go outside the user's scope, the only reference to
them left is the weakref in the cache, and they can be garbage
collected. Then, if the user requests it again, it can be returned if
it's not GC'd yet, or regenerated and returned if it has.
It seems, though, that the WeakRef implementation is such that if you
refer to an object other than via its weakref, the weakref-ness is
destroyed and the object never gets GC'd. Can anyone explain why and/or
offer a way around this?
Tim Bates