I've noticed that objects have their IDs assigned in a counterintuitive fashion. The earlier an object is created, the greater its object ID. I would have thought they would have been assigned in ascending order, rather than the other way around.
For example:
obj1 = Object.new
obj2 = Object.new
obj3 = Object.new
p obj1.object_id # => 4806560
p obj2.object_id # => 4806540
p obj3.object_id # => 4806520
Why are they assigned in such a way and also why is there a step of 20, rather than 1 in code run by the Ruby interpreter, but a vastly greater difference between object IDs for code run by Ruby's irb?
Handwaving over many details, ruby allocates a chunk of the heap to put objects in:
1 | 2 | 3 | 4 | 5
Then traverses them in-order and adds them to a linked-list of free objects. This causes them to be in reverse order on the linked-list:
freelist → NULL
freelist → 1 → NULL
freelist → 2 → 1 → NULL
freelist → 3 → 2 → 1 → NULL
freelist → 4 → 3 → 2 → 1 → NULL
freelist → 5 → 4 → 3 → 2 → 1 → NULL
When allocating an object ruby uses the first item on the linked list:
object = freelist
freelist = object.next_free
So the freelist now looks like:
freelist → 4 → 3 → 2 → 1 → NULL
and further allocated objects will appear in reverse order across small allocations.
When ruby needs to allocate a new chunk of heap to store more objects you'll see the object_id jump up then run down again.
The Ruby interpreter is a C program, you are probably looking at the corresponding memory addresses of the objects.
For what it's worth, you can see a totally different progression on different implementations; everyone allocates their objects in a different way, with different-sized buckets.
MRI 1.9.3
objs = [Object.new, Object.new, Object.new]
objs.each {|o| puts o.object_id}
# 70257700803740
# 70257700803700
# 70257700803680
JRUBY
objs = [Object.new, Object.new, Object.new]
objs.each {|o| puts o.object_id}
# 2048
# 2050
# 2052
RBX
objs = [Object.new, Object.new, Object.new]
objs.each {|o| puts o.object_id}
# 3920
# 3924
# 3928
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With