object_id 分配如何工作? [英] How does object_id assignment work?
问题描述
我正在使用 Ruby 的 .object_id
并注意到,在 irb 的几个连续会话中,我得到了这些相同的结果:
I'm playing around with Ruby's .object_id
and noticed that, in several sequential sessions of irb, I get these identical results:
false.object_id // 0
true.object_id // 2
nil.object_id // 4
100.object_id // 201
实际上,每个整数的 object_id 似乎都是 ((value * 2) + 1).
In fact, every integer's object_id seems to be ((value * 2) + 1).
另一方面,在退出并重新运行 irb 后,给定字符串的 object_id 永远不会相同.
On the other hand, a given string's object_id is never the same after exiting and re-running irb.
这给我带来了几个问题:
This raises several questions for me:
- 是否有确定某些
object_id
的已知方案?其他的基本上是随机的吗? - true、false 和 nil 的 id 不是连续的.有没有办法询问给定的 id 代表什么对象?(我很好奇其他个位数和 ID 与什么相关.)
- 您能否(不是您应该)编写混淆的 Ruby,在其中使用已知的对象 ID 来引用对象而不命名它们,例如id 201 的对象 + id 19 的对象"?意思是100 + 9"?
- Is there a known scheme by which certain
object_id
s are determined? Are others basically random? - The ids for true, false, and nil, aren't sequential. Is there a way to ask what object is represented by a given id? (I'm curious what the other single-digit and ids are tied to.)
- Could you (not that you should) write obfuscated Ruby where you use known object ids to refer to objects without naming them, like "object of id 201 + object of id 19" to mean "100 + 9"?
更新
根据 Andrew Grimm 的建议,我尝试发现其他低 ID"对象,但发现:
Update
Using Andrew Grimm's suggestion, I tried discovering other "low id" objects, but found that:
- 此序列中似乎没有更多偶数对象 - ids 6、8、10 等不指向任何内容.
- 正如我之前的实验所暗示的,所有奇数 ID 都属于数字.具体来说,id 1 指向数字 0,3 指向 1,5 指向 2,依此类推.
推荐答案
在 MRI 中,对象的 object_id
与表示对象上的 VALUE
相同C级.对于大多数类型的对象,这个 VALUE
是指向内存中存储实际对象数据的位置的指针.显然这在多次运行时会有所不同,因为它只取决于系统决定分配内存的位置,而不取决于对象本身的任何属性.
In MRI the object_id
of an object is the same as the VALUE
that represents the object on the C level. For most kinds of objects this VALUE
is a pointer to a location in memory where the actual object data is stored. Obviously this will be different during multiple runs because it only depends on where the system decided to allocate the memory, not on any property of the object itself.
但是出于性能原因,true
、false
、nil
和 Fixnum
被特殊处理.对于这些对象,内存中实际上没有包含对象数据的结构.对象的所有数据都在 VALUE
本身中编码.正如您已经计算出false
、true
、nil
和任何Fixnum
i
,分别是0
、2
、4
和i*2+1
.
However for performance reasons true
, false
, nil
and Fixnum
s are handled specially. For these objects there isn't actually a struct with the object's data in memory. All of the object's data is encoded in the VALUE
itself. As you already figured out the values for false
, true
, nil
and any Fixnum
i
, are 0
, 2
, 4
and i*2+1
respectively.
这样做的原因是在任何运行 MRI 的系统上,0
、2
、4
和 i*2+1
永远不是堆上对象的有效地址,因此不会与指向对象数据的指针重叠.
The reason that this works is that on any systems that MRI runs on, 0
, 2
, 4
and i*2+1
are never valid addresses for an object on the heap, so there's no overlap with pointers to object data.
这篇关于object_id 分配如何工作?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!