2013-03-17 50 views
0

为什么ObjectSpace._id2ref在Ruby 1.9和Ruby 2.0上有不同的输出?为什么`ObjectSpace._id2ref`在Ruby 1.9和Ruby 2.0上提供不同的输出?

红宝石1.9.3p392 I386-mingw32的

class Foo ; end 

Foo.object_id      #=> 17569464 
ObjectSpace._id2ref(17569464)  #=> Foo 

Foo.new.singleton_class.object_id #=> 17075124 
ObjectSpace._id2ref(17075124)  #=> "\x00" 

红宝石2.0.0p0 I386-mingw32的

class Foo ; end 

Foo.object_id      #=> 17197176 
ObjectSpace._id2ref(17197176)  #=> Foo 

Foo.new.singleton_class.object_id #=> 19181436 
ObjectSpace._id2ref(19181436)  #=> RangeError: 0x124af7c is recycled object 

Foo.new.singleton_class.object_id #=> 17454324 
ObjectSpace._id2ref(17454324)  #=> RangeError: 0x10a54f4 is not id value 

Foo.new.singleton_class.object_id #=> 17139816 
ObjectSpace._id2ref(17139816)  #=> "c" 

回答

1

只是因为在2.0垃圾收集器是defter。对于

# RangeError: 0x124af7c is recycled object 

状态的对象已经GC'ed

UPD:我们可以Mutex接近要求的行为:

2.0.0 (main):0 > Mutex.new.synchronize { 
2.0.0 (main):0 * class Foo ; end 
2.0.0 (main):0 * id = Foo.new.singleton_class.object_id 
2.0.0 (main):0 * puts id 
2.0.0 (main):0 * puts ObjectSpace._id2ref(id) 
2.0.0 (main):0 * } 
# 23172260 
# <Class:#<Foo:0x00000002c32970>> 
+0

请参阅我的'EDIT'。使用Ruby2.0输出更改 – 2013-03-17 08:32:47

+0

您正在尝试打印出已经清除的内存堆。一切都可能被打印出来,这样做没有合同。尝试至少包含调用'new'和'_id2ref'进入互斥锁。 – mudasobwa 2013-03-17 08:37:00

+0

你的建议对我很有价值,所以你的建议是什么,你可以把它写入你的答案吗? – 2013-03-17 08:39:56