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?
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.
Der Ruby-Interpreter ist ein C-Programm, wahrscheinlich sehen Sie sich die entsprechenden Speicheradressen der Objekte an.
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% 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.
Tags und Links ruby irb object-identity