为什么object_id会在windows上持续存在而不在linux上?

sai*_*ala 6 ruby windows objectid

这个计划

class ObjectGarden
    class << self.clone
            puts self.object_id
    end
end

puts ObjectGarden.clone.object_id
Run Code Online (Sandbox Code Playgroud)

在Linux上运行(已在RHEL上测试)object_id在多次运行中生成不同的s,如我所料.但是,当我在Windows上运行它时,我会在多次运行中获得相同的输出.而且不管我做什么(休眠/关机/"臭名昭着的蓝屏"并重启)object_ids都不会改变.

我还注意到,object_id如果我更改了程序的内容(甚至是一个无关紧要的更改,如添加新行或注释),那么在Windows上进行更改.

为什么Windows和Linux实现之间存在这种差异?由于我无法访问OS X,有人可以在Mac上运行它并记录结果.

我在Windows上使用Ruby 1.9.2-p136,在Linux上使用Ruby 1.9.2-p180.

Mic*_*ade 1

对于 ruby​​ 中的大多数对象,您获得的数字#object_id实际上是指向该对象的内部 C 数据结构的指针。该数据结构又由 ruby​​ 实现/构建使用的任何内存分配器为其分配空间。

如果不阅读代码,我会猜测 linux 版本每次都会产生不同的结果,因为 ruby​​ 或 C 分配器故意使用随机偏移量进行分配或指针,以使它们难以猜测,从而使程序更容易安全的。

ruby 对 's 的保证只有一个object_id:只要特定对象存在,它object_id对于该 ruby​​ 解释器来说就是唯一的,并且不会改变。就这样。如果对象最终获得相同的内存块,您甚至可以获得object_id与先前创建的对象相同的对象,然后进行垃圾收集。

另请注意,如果您执行以下操作:

irb(main):001:0> a = "hi"
=> "hi"
irb(main):002:0> a.object_id
=> 14348380
irb(main):003:0> a = a + " there"
=> "hi there"
irb(main):004:0> a.object_id
=> 14197020
Run Code Online (Sandbox Code Playgroud)

该行a = a + " there"实际上创建了一个新对象,带有 new object_id,而 using 则#concat不然:

irb(main):005:0> a = "hi"
=> "hi"
irb(main):006:0> a.object_id
=> 12031400
irb(main):007:0> a.concat " there"
=> "hi there"
irb(main):008:0> a.object_id
=> 12031400
Run Code Online (Sandbox Code Playgroud)

另请注意,在 ruby​​ 中,赋值将分配的变量绑定到对象,因此将一个变量分配给另一个变量将它们指向同一个对象:

irb(main):011:0> a = "hi"
=> "hi"
irb(main):012:0> a.object_id
=> 12081640
irb(main):013:0> b = a
=> "hi"
irb(main):014:0> b.object_id
=> 12081640
Run Code Online (Sandbox Code Playgroud)

因此改变一个变量将会改变另一个变量:

irb(main):015:0> a.concat " there"
=> "hi there"
irb(main):016:0> b
=> "hi there"
Run Code Online (Sandbox Code Playgroud)