8

オブジェクトには直感に反する方法で ID が割り当てられていることに気付きました。オブジェクトの作成が早ければ早いほど、そのオブジェクト ID は大きくなります。逆ではなく、昇順で割り当てられていると思っていたでしょう。

例えば:

obj1 = Object.new
obj2 = Object.new
obj3 = Object.new

p obj1.object_id # => 4806560
p obj2.object_id # => 4806540
p obj3.object_id # => 4806520

また、Ruby インタープリターによって実行されるコードでは 1 ではなく 20 のステップがあるのに、Ruby の irb によって実行されるコードのオブジェクト ID の差が非常に大きいのはなぜですか?

4

4 に答える 4

14

多くの詳細をハンドウェイブすることで、Ruby はオブジェクトを配置するためにヒープのチャンクを割り当てます。

1 | 2 | 3 | 4 | 5

次に、それらを順番にトラバースし、フリー オブジェクトのリンク リストに追加します。これにより、リンクされたリストでそれらが逆順になります。

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

オブジェクトを割り当てるとき、ruby はリンクされたリストの最初の項目を使用します:

object = freelist
freelist = object.next_free

したがって、フリーリストは次のようになります。

freelist → 4 → 3 → 2 → 1 → NULL

さらに割り当てられたオブジェクトは、小さな割り当て全体で逆の順序で表示されます。

ruby がより多くのオブジェクトを格納するためにヒープの新しいチャンクを割り当てる必要がある場合、object_id がジャンプアップしてから再びダウンすることがわかります。

于 2012-05-03T00:38:18.497 に答える
2

Ruby インタープリターは C プログラムです。おそらく、オブジェクトの対応するメモリーアドレスを見ているでしょう。

于 2012-05-03T00:24:15.260 に答える
2

価値があるのは、さまざまな実装でまったく異なる進行状況を見ることができるということです。誰もが異なるサイズのバケットを使用して、異なる方法でオブジェクトを割り当てます。

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
于 2012-05-03T03:59:27.417 に答える
0

オブジェクト ID のログを実行したところ、物事は順調に進んでいるように見えましたが、ガベージ コレクションによって時々逆の方向に進んでいるよう2080見えました。しかし、Ruby が保持する内部オブジェクトの量を考慮すると、オブジェクト ID の順序に依存する必要はありません。また、Ruby がローカル プラットフォームの最上位から開始するintshort、実行を簡単にテストできるようにすることもできます ( if(current_id==0) { problem })。さまざまな数字から私が見たものからすると、それは完全に異なっており、決定できないようです. Ruby がオブジェクトへのポインターを使用しているように (ほぼ) 見えます。これは一意であることが保証されており、オブジェクト間の巨大なギャップ (20 バイト) を説明するためです。によって返された値を見るとobject_id、私のシステムのネイティブ ポインター サイズ (64 ビット Intel) の横にあるそれを見てください。

へのポインターを出力した同じシステムでテスト C++ プログラムを実行したところintです。ポインター (10 進数) は140734848324996で、Ruby オブジェクト ID は でした70118105405380。数字に共通点はあまりありませんが、どちらも同じ範囲にあり、ポインターのように見えます。

もちろん、誰かがRubyのソースを掘り下げて見つけてくれれば、それが明確な答えになるでしょう。私はしようとしています。

于 2012-05-03T00:32:19.907 に答える