Warum ordnet Ruby Objekt-IDs in absteigender Reihenfolge an?

8

Ich habe bemerkt, dass Objekten ihre IDs in einer nicht intuitiven Weise zugewiesen werden. Je früher ein Objekt erstellt wird, desto größer ist seine Objekt-ID. Ich hätte gedacht, dass sie in aufsteigender Reihenfolge zugewiesen worden wären, anstatt umgekehrt.

Zum Beispiel:

%Vor%

Warum werden sie so zugewiesen und warum gibt es einen Schritt von 20 statt 1 in Code, der vom Ruby-Interpreter ausgeführt wird, aber ein wesentlich größerer Unterschied zwischen Objekt-IDs für Code, der von Ruby's irb ausgeführt wird?

    
Matty 03.05.2012, 00:05
quelle

4 Antworten

14

Handwaving über viele Details, Ruby reserviert einen Teil des Heaps, um Objekte in:

%Vor%

Durchläuft sie dann in der Reihenfolge und fügt sie zu einer verknüpften Liste von freien Objekten hinzu. Dies führt dazu, dass sie in umgekehrter Reihenfolge auf der verknüpften Liste stehen:

%Vor%

Bei der Zuweisung eines Objekts verwendet ruby ​​das erste Element der verknüpften Liste:

%Vor%

Die Freelist sieht nun so aus:

%Vor%

und weitere zugeordnete Objekte erscheinen in umgekehrter Reihenfolge über kleine Zuordnungen.

Wenn Ruby einen neuen Chunk von Heap zuweisen muss, um weitere Objekte zu speichern, wird die object_id hochspringen und dann wieder runter laufen.

    
drbrain 03.05.2012, 00:38
quelle
2

Der Ruby-Interpreter ist ein C-Programm, wahrscheinlich sehen Sie sich die entsprechenden Speicheradressen der Objekte an.

    
Erik Petersen 03.05.2012 00:24
quelle
2

Für was es wert ist, können Sie eine völlig andere Entwicklung bei verschiedenen Implementierungen sehen; Jeder weist seine Objekte auf andere Weise zu, mit unterschiedlich großen Buckets.

MRT 1.9.3

%Vor%

JRUBY

%Vor%

RBX

%Vor%     
Bill Dueber 03.05.2012 03:59
quelle
0

Ich habe gerade ein Logbuch mit Objekt-IDs erstellt, und es schien, als ob die Dinge in Ordnung liefen, aber die Müllsammlung schien die Dinge hin und wieder in die andere Richtung zu treiben. Ich sah Sprünge von wie 20 bis 80 Es scheint also fast zufällig zu sein. Aber mit der Menge an internen Objekten, die Ruby unterhält, sind Objekt-ID-Befehle nichts, auf die man sich verlassen kann. Es könnte auch sein, dass Ruby an der Spitze der lokalen Plattform int oder short startet, um einen einfachen Test für das Auslaufen zu ermöglichen ( if(current_id==0) { problem } ). Nach dem, was ich von unseren verschiedenen Zahlen gesehen habe, scheint es völlig anders und nicht bestimmbar zu sein. Es sieht (fast) so aus, als würde Ruby sogar den Zeiger auf das Objekt verwenden, weil das eindeutig ist und die riesigen Lücken (20 Bytes) zwischen Objekten erklären würde. Wenn ich mir den von object_id zurückgegebenen Wert anschaue und ihn neben der nativen Zeigergröße meines Systems (64-Bit Intel) ansehe.

Ich habe gerade ein C ++ - Testprogramm auf demselben System ausgeführt, das einen Zeiger auf ein int ausgedruckt hat. Der Zeiger (dezimal) war 140734848324996 und die Ruby-Objekt-ID war 70118105405380 . Die Zahlen haben nicht viel gemeinsam, aber sie sind beide im selben Bereich und sehen so aus wie Zeiger.

Natürlich, wenn jemand in die Ruby-Quelle eindringen und herausfinden würde, wäre das die definitive Antwort. Ich versuche es.

    
Linuxios 03.05.2012 00:32
quelle

Tags und Links