Frage

Was ist das Speicherlayout eines .NET-Array?

zum Beispiel Nehmen Sie dieses Array:

Int32[] x = new Int32[10];

Ich verstehe, dass der Großteil des Arrays ist wie folgt:

0000111122223333444455556666777788889999

wobei jedes Zeichen ein Byte ist, und die Ziffern entsprechen Indizes in das Array.

Außerdem weiß ich, dass es eine Art Referenz, und ein Synchronisationsblock-Index für alle Objekte, so kann die oben auf diese eingestellt werden:

ttttssss0000111122223333444455556666777788889999
        ^
        +- object reference points here

Darüber hinaus muss die Länge des Arrays gespeichert werden, so vielleicht ist dies mehr richtig:

ttttssssllll0000111122223333444455556666777788889999
        ^
        +- object reference points here

Ist dieser Vorgang abgeschlossen? Gibt es noch mehr Daten in einem Array?

Der Grund, ich frage ist, dass wir zu schätzen, sind versucht, wie viel Speicher ein paar verschiedene In-Memory-Darstellungen eines ziemlich großen Datenkorpus nehmen und die Größe der Arrays variiert ziemlich viel, so dass der Overhead könnte einen großen Einfluss in einer Lösung, aber vielleicht nicht so sehr in dem anderes.

Also im Grunde für ein Array, wie viel Aufwand es ist, das ist im Grunde meine Frage.

Und vor dem Arrays sind schlecht Kader aufwacht, ist dieser Teil der Lösung ist eine statische Aufladung einmal referenz oft Art der Sache so wachstumsfähige Listen verwendet, ist hier nicht erforderlich.

War es hilfreich?

Lösung

Gute Frage. Ich fand this Artikel, die Blockdiagramme für beide Werttypen und Referenztypen enthält. Siehe auch diese Artikel rel="nofollow denen Ritcher heißt:

  

[snip] jedes Array hat einige zusätzliche   Overhead-Informationen im Zusammenhang mit   es. Diese Information enthält den Rang   des Arrays (Anzahl der Dimensionen),   die unteren Grenzen für jede Dimension von   das Array (fast immer 0), und die   Länge jeder Dimension. der Overhead   enthält auch die Art jedes Elements   in der Anordnung.

Andere Tipps

Eine Möglichkeit, dies zu untersuchen, ist auf dem Code in WinDbg zu suchen. Also angesichts der Code unten, mal sehen, wie das auf dem Heap angezeigt wird.

var numbers = new Int32[] { 0, 1, 2, 3, 4, 5, 6, 7, 8, 9 };

Das erste, was zu tun ist, um die Instanz zu lokalisieren. Wie ich gemacht habe in Main() eine dieser lokalen, es ist einfach die Adresse der Instanz zu finden.

Von der Adresse wir die eigentliche Instanz Dump können, die es uns gibt:

0:000> !do 0x0141ffc0
Name: System.Int32[]
MethodTable: 01309584
EEClass: 01309510
Size: 52(0x34) bytes
Array: Rank 1, Number of elements 10, Type Int32
Element Type: System.Int32
Fields:
None

Das sagt uns, dass es unsere Int32 Array mit 10 Elementen und einer Gesamtgröße von 52 Byte ist.

Lassen Sie uns das Speicherabbild in dem die Instanz befindet.

0:000> d 0x0141ffc0
0141ffc0 [84 95 30 01 0a 00 00 00-00 00 00 00 01 00 00 00  ..0.............
0141ffd0  02 00 00 00 03 00 00 00-04 00 00 00 05 00 00 00  ................
0141ffe0  06 00 00 00 07 00 00 00-08 00 00 00 09 00 00 00  ................
0141fff0  00 00 00 00]a0 20 40 03-00 00 00 00 00 00 00 00  ..... @.........
01420000  00 00 00 00 00 00 00 00-00 00 00 00 00 00 00 00  ................
01420010  10 6d 99 00 00 00 00 00-00 00 01 40 50 f7 3d 03  .m.........@P.=.
01420020  03 00 00 00 08 00 00 00-00 01 00 00 00 00 00 00  ................
01420030  1c 24 40 03 00 00 00 00-00 00 00 00 00 00 00 00  .$@.............

Ich habe Klammern für die 52 Bytes eingefügt.

  • Die ersten vier Bytes sind die Referenz auf die Methodentabelle auf 01309584.
  • Dann vier Bytes für die Länge des Arrays.
  • Die folgenden, die die Zahlen 0 bis 9 (jede vier Bytes).
  • Die letzten vier Bytes sind null. Ich bin nicht ganz sicher, aber ich denke, das muss sein, wo der Verweis auf den Synchronisationsblock-Array gespeichert wird, wenn die Instanz zum Verriegeln verwendet wird.

Edit: Vergessen Länge in erstem Posting

.

Die Auflistung ist etwas falsch, weil als romkyns die Instanz beginnt an der Adresse tatsächlich weist darauf hin - 4 und das erste Feld ist der Synchronisationsblock.

Gute Frage! Ich wollte es für mich sehen, und es schien eine gute Gelegenheit, auszuprobieren Cordbg.exe ...

Sie scheint, dass für einfachen Integer-Arrays, das Format ist:

ssssllll000011112222....nnnn0000

, wobei S der Synchronisationsblock ist, L die Länge des Arrays, und dann werden die einzelnen Elemente. Es scheint, dass es ein endlich 0 am Ende ist, ich bin nicht sicher, warum das so ist.

Für mehrdimensionale Arrays:

ssssttttl1l1l2l2????????
    000011112222....nnnn000011112222....nnnn....000011112222....nnnn0000

wobei s der Sync-Block, t die Gesamtzahl der Elemente, die Länge der ersten Dimension L1, L2 die Länge der zweiten Dimension, dann zwei Nullen ?, gefolgt von allen Elementen der Reihe und ein schließlich wieder Null .

Objektarrays als Integer-Array behandelt werden, werden die Inhalte dieses Mal Referenzen. Jagged Arrays sind Gegenstand Arrays, bei denen die Verweise auf andere Arrays verweisen.

Ein Array Objekt würde zu speichern, wie viele Dimensionen hat und die Länge jeder Dimension. So gibt es mindestens ein weiteres Datenelement zu Ihrem Modell hinzufügen

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top