Ein naives Typsystem würde Objekte als Zeiger auf seinen Typ speichern (der viele nützliche Informationen enthält, wie eine V-Tabelle, Objektgröße usw.), gefolgt von seinen Daten. Wenn .Net ein solches Typsystem hätte, würde ein object
bei einem 32-Bit-System 4 Bytes und bei 64-Bit 8 Bytes belegen.
Wir können sehen, dass es nicht ist >. Der Objekt-Overhead besteht aus zwei Zeigergrößen, außerdem gibt es eine "minimale" Größe von einer weiteren Zeigergröße.
Also, was speichert object
tatsächlich hinter den Kulissen?
Ja, so sieht es aus. Der 'Typ-Handle', auch 'Methodentabellenzeiger' genannt, ist bei Offset 0, die Objektdaten folgen bei Offset 4. Bei Offset-4 gibt es ein zusätzliches Feld namens 'Syncblock'. Es ist dort, weil es auch an dem Garbage-Collected-Heap teilnimmt, wenn der Objektraum nicht verwendet wird, eine doppelt verknüpfte Liste von freien Blöcken, die zwei Zeiger benötigt. Damit es nicht verschwendet wird, hat der Syncblock mehrere Verwendungsmöglichkeiten, wie Speichern des Sperrzustands, Speichern des Hash-Codes, Speichern eines Zeigers auf einen expliziten Syncblock, wenn zu viel gespeichert werden muss.
Das kleinstmögliche Objekt ist für ein Box-Byte, 4 + 4 + 1 = 9 Bytes. Die Zuordnungsgranularität für den GC-Heap beträgt jedoch 4 Byte, sodass Sie das nächste Vielfache von 4, 12 Byte erhalten.
Dies ist alles gut sichtbar mit dem Debugger in Visual Studio. Sie finden Hinweise in diese Antwort .
(Dies ist alles aus der Microsoft Shared Source CLI ; es enthält den Quellcode der CLR.
Wenn Sie sich clr\src\vm\object.h
ansehen, sehen Sie:
was ziemlich selbsterklärend ist. Außerdem können Sie in clr\src\vm\gcscan.cpp
Anweisungen wie
oder
%Vor%was erklärt, warum Sie die unerwarteten Objektgrößen sehen. :)
Aktualisierung:
@Hans hatte einen großen Punkt auf dem Sync-Block; Ich möchte nur auf eine Subtilität hinweisen, die wiederum in object.h
dokumentiert ist:
Beachten Sie diesen Teil:
Der Sync-Block-Index befindet sich tatsächlich bei einem negativen Offset für die Instanz.
Also folgt der Sync-Block scheinbar nicht der Methodentabelle (wie Hans schon erwähnt hat), aber es kommt vor - es ist also kein "normales" Teil des Objekts (für das Fehlen eines besseren Wortes).