[ruby-core:121948] [Ruby Feature#15408] Deprecate ObjectSpace._id2ref

Issue #15408 has been updated by Dan0042 (Daniel DeLorme). headius (Charles Nutter) wrote in #note-44:
I'd also like to know **why** you want `_id2ref` to stick around.
I think that question is backwards. There is no need for any reason to keep existing functionality; backward compatibility should be the default. The question is rather **why** you want `_id2ref` to be deprecated, since the previous reason given was no longer applicable. I don't think the memory usage of the id-to-ref mapping is much of a concern, but I agree that the synchronization issue with Ractors explained in [1] makes it fairly reasonable to deprecate this API. I imagine `_id2ref` *could* be fixed to mostly avoid synchronization by using one lookup table per Ractor + one table for shareable objects, but that sounds like a fairly complex fix and probably not worth the trouble. [1]https://byroot.github.io/ruby/performance/2025/04/26/unlocking-ractors-objec... ---------------------------------------- Feature #15408: Deprecate ObjectSpace._id2ref https://bugs.ruby-lang.org/issues/15408#change-113068 * Author: headius (Charles Nutter) * Status: Closed * Assignee: headius (Charles Nutter) ---------------------------------------- Ruby currently provides the object_id method to get a "identifier" for a given object. According to the documentation, this ID is the same for every object_id call against a given object, and guaranteed not to be the same as any other active (i.e. alive) object. However, no guarantee is made about the ID being reused for a future object after the original has been garbage collected. As a result, object_id can't be used to uniquely identify any object that might be garbage collected, since that ID may be associated with a completely different object in the future. Ruby also provides a method to go from an object_id to the object reference itself: ObjectSpace._id2ref. This method has been in Ruby for decades and is often used to implement a weak hashmap from ID to reference, since holding the ID will not keep the object alive. However due to the problems with object_id not actually being unique, it's possible for _id2ref to return a different object than originally had that ID as object slots are reused in the heap. The only way to implement object_id safely (with idempotency guarantees) would be to assign to all objects a monotonically-increasing ID. Alternatively, this ID could be assigned lazily only for those objects on which the code calls object_id. JRuby implements object_id in this way currently. The only way to implement _id2ref safely would be to have a mapping in memory from those monotonically-increasing IDs to the actual objects. This would have to be a weak mapping to prevent the objects from being garbage collected. JRuby currently only supports _id2ref via a flag, since the additional overhead of weakly tracking every requested object_id is extremely high. An alternative for MRI would be to implement _id2ref as a heap scan, as it is implemented in Rubinius. This would make it entirely unpractical due to the cost of scanning the heap for every ID lookup. I propose that both methods should immediately be deprecated for removal in Ruby 3.0. * They do not do what people expect. * They cannot reliably do what they claim to do. * They eventually lead to difficult-to-diagnose bugs in every possible use case. Put simply, both methods have always been broken in MRI and making them unbroken would render them useless. -- https://bugs.ruby-lang.org/
participants (1)
-
Dan0042 (Daniel DeLorme)