Forum: Ruby-core [ruby-trunk - Feature #6309][Open] Add a reference queue for weak references

Posted by Charles Nutter (headius)
on 2012-04-17 10:10
(Received via mailing list)
Issue #6309 has been reported by headius (Charles Nutter).

----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309

Author: headius (Charles Nutter)
Status: Open
Priority: Normal
Assignee:
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-04-19 21:51
(Received via mailing list)
Issue #6309 has been updated by mame (Yusuke Endoh).

Status changed from Open to Feedback

There is no maintainer for weakref, so please create a patch yourself!
We may import it if matz accepts.

BTW, the name "reference queue" is very bad, I think.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-26025

Author: headius (Charles Nutter)
Status: Feedback
Priority: Normal
Assignee:
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by Charles Nutter (headius)
on 2012-04-28 07:48
(Received via mailing list)
Issue #6309 has been updated by headius (Charles Nutter).


Ok, fair enough.

Here is a *very primitive* modification of the current weakref.rb to 
support a reference queue. I need to stress that I don't think this is 
the best way to implement it; a hook into the GC cycle that inserts 
weakrefs into a purpose-built reference queue would be better than using 
finalizers in this way. But the API would largely work the same.

Patch: https://gist.github.com/2516338

Example usage: https://gist.github.com/2516355

This works mostly like I expect a reference queue to work, but there are 
many inefficiencies here:

* Polling the reference queue needs to be as close to free as possible. 
The current Queue implementation raises an exception when empty, which 
is very far from being free.
* A Ruby-level finalizer is much more expensive than a purpose-built 
native GC hook would be.
* A Ruby-based Queue is much more expensive than a purpose-built 
reference queue would be.

I know that in past discussions about improving weakref support in Ruby 
there were C-level patches to add all the features I'm looking for, and 
I'll try to dig up those discussions and patches. But hopefully this 
illustrates what I'm looking for in a primitive way.
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-26280

Author: headius (Charles Nutter)
Status: Feedback
Priority: Normal
Assignee:
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-05-03 04:29
(Received via mailing list)
Issue #6309 has been updated by mame (Yusuke Endoh).


Ah, I knew what you are proposing by seeing Javadoc:

http://docs.oracle.com/javase/1.4.2/docs/api/java/...
http://docs.oracle.com/javase/6/docs/api/java/lang..., 
java.lang.ref.ReferenceQueue)

I don't know the (real-world) use case of the feature, though.


Anyway, I mean I'd like you to create a patch written *in C*.
If there is a patch that we can review and import "as is",
I will be happy to assign this ticket to some core committers,
such as ko1 and kosaki.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-26401

Author: headius (Charles Nutter)
Status: Feedback
Priority: Normal
Assignee:
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-05-03 04:51
(Received via mailing list)
Issue #6309 has been updated by mame (Yusuke Endoh).

Status changed from Feedback to Assigned
Assignee set to matz (Yukihiro Matsumoto)

On second thought, the proposal should first get an approval from matz. 
Sorry.  Assigning this to him.
Still, it would be helpful to show a concrete use case, I think.

--
Yusuke Endoh <mame@tsg.ne.jp>
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-26402

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by Charles Nutter (headius)
on 2012-05-03 23:00
(Received via mailing list)
Issue #6309 has been updated by headius (Charles Nutter).


I linked to a concrete use case in the original report...an 
implementation of a "weak ID map" entirely in Ruby without scanning for 
dead references: 
https://github.com/headius/weakling/blob/master/li...

It is not possible to implement weak data structures efficiently without 
a reference queue, since you would be forced to periodically do an O(N) 
scan for dead references to clean them out.
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-26432

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by Charles Nutter (headius)
on 2012-11-16 17:27
(Received via mailing list)
Issue #6309 has been updated by headius (Charles Nutter).


Seven months and no activity. Can we get a reference queue in Ruby 2.0 
please? I believe it could be added to weakref.rb using 2.0's WeakHash, 
or built atop the C code that implements WeakHash (since it contains 
most of a reference queue implementation already).
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-32973

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version:


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by mame (Yusuke Endoh) (Guest)
on 2012-11-24 02:57
(Received via mailing list)
Issue #6309 has been updated by mame (Yusuke Endoh).

Target version set to next minor


----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-33723

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version: next minor


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Posted by Charles Nutter (headius)
on 2013-03-15 18:30
(Received via mailing list)
Issue #6309 has been updated by headius (Charles Nutter).


I request a ruling by matz about adding a ReferenceQueue to weakref.rb.
----------------------------------------
Feature #6309: Add a reference queue for weak references
https://bugs.ruby-lang.org/issues/6309#change-37635

Author: headius (Charles Nutter)
Status: Assigned
Priority: Normal
Assignee: matz (Yukihiro Matsumoto)
Category:
Target version: next minor


Most interesting uses of WeakRef are much harder to do efficiently 
without a reference queue.

A reference queue, as implemented by the JVM, is basically a queue into 
which weak references are placed some time after the object they refer 
to has been collected. The queue can be polled cheaply to look for 
collected references.

A simple example of usage can be seen in the weakling gem, with an 
efficient implementation of an ID hash: 
https://github.com/headius/weakling/blob/master/li...

Notice the _cleanup method is called for every operation, to keep the 
hash clear of dead references. Failure to have a _cleanup method would 
mean the hash grows without bounds.

_cleanup cannot be implemented efficiently on MRI at present because 
there's no reference queue implementation. On MRI, _cleanup would have 
to perform a linear scan of all stored values periodically to search for 
dead references. For a heavily used hash with many live values, this 
becomes a very expensive operation.

It's probably possible to implement reference queues efficiently atop 
the new ObjectSpace::WeakMap internals, since it already keeps track of 
weak references and can run code when a weak reference no longer refers 
to a live object.
Please log in before posting. Registration is free and takes only a minute.
Existing account (Switch to SSL-encrypted connection)
NEW: Do you have a Google/GoogleMail or Yahoo account? No registration required!
Log in with Google account | Log in with Yahoo account
No account? Register here.