3

At least up to a little more than 20_000_000, the object_ids of numbers are 2 times the number + 1:

1454.object_id # => 2909

When calling the object_id on large numbers, this format is not kept. It seems like there is a built in limit to the number of objects you could theoretically have. I ran:

ids = []
100_000_000.times { ids << String.new.object_id }
ids.max # => 22314984
ids.uniq.count # => 44301

So out of the 100,000,000 string objects, only about 50,000 were actually unique. That means 99.95% of these objects were the same object. I'm not sure why this is.

sawa
  • 165,429
  • 45
  • 277
  • 381
Richard Hamilton
  • 25,478
  • 10
  • 60
  • 87
  • I believe it is limited by the amount of memory server has, but this is only my opinion. – Rustam Gasanov Mar 25 '15 at 16:18
  • Just ran this. No, it didn't raise any errors. I doubt it's helpful though, the hypothetical limit could be higher. – D-side Mar 25 '15 at 16:21
  • You ran this code without a `MemoryAllocationError`? – Richard Hamilton Mar 25 '15 at 16:21
  • You might want to read answers [given here](http://stackoverflow.com/questions/3430280/how-does-object-id-assignment-work). – D-side Mar 25 '15 at 16:24
  • @user4703663 Yes. 100 million strings is not very much for a modern computer. – user229044 Mar 25 '15 at 16:24
  • Alright, I ran `ids.max` and got `22314984`. When I ran `ids.uniq.count`, I only got `44301`. This means that different strings are the same object. Is this part of `GC` or is there a different explanation? – Richard Hamilton Mar 25 '15 at 16:31
  • 1
    You create 100000000 strings, but they aren't alive at the same time. Your array only stores their IDs and the strings are left unreferenced. Now the GC may collect them and if that happens a new object can have the same ID as an already collected one since its slot is free. – cremno Mar 25 '15 at 17:24

1 Answers1

6

How object ids are allocated is implementation dependant. On C-ruby, object id is just the numerical value of the memory address of the object (with some exceptions for immediate values such as true, false, nil, Fixnums).

Therefore two live objects can't share the same object id (good!), however if you trigger a garbage collection then some of the memory locations (i.e. heap slots) may be reused and therefore the object ids too.

Another consequence is that you'll never run out of object ids (unless you exhaust the address space of the process, but you're in trouble anyway if that happens)

Frederick Cheung
  • 83,189
  • 8
  • 152
  • 174
  • For reference, [this](https://github.com/ruby/ruby/blob/4e8fbe17787fe3d46431087f791ed443b1010e19/gc.c#L2873) is how `object_id` is implemented in current MRI. – D-side Mar 25 '15 at 16:53