Question

Quelle est la disposition de la mémoire d'un tableau .NET?

Prenez par exemple ce tableau:

Int32[] x = new Int32[10];

Je comprends que le gros du tableau ressemble à ceci:

0000111122223333444455556666777788889999

Où chaque caractère est un octet et les chiffres correspondent aux index du tableau.

De plus, je sais qu’il existe une référence de type et un index de blocage de bloc pour tous les objets. Vous pouvez donc ajuster ce qui précède à ceci:

ttttssss0000111122223333444455556666777788889999
        ^
        +- object reference points here

De plus, la longueur du tableau doit être stockée, alors c'est peut-être plus correct:

ttttssssllll0000111122223333444455556666777788889999
        ^
        +- object reference points here

Est-ce complet? Y a-t-il plus de données dans un tableau?

La raison pour laquelle je vous pose cette question est que nous essayons d'estimer la quantité de mémoire que prendront deux représentations différentes en mémoire d'un corpus de données assez volumineux et que la taille des tableaux varie un peu, de sorte que pourrait avoir un impact important dans une solution, mais peut-être pas autant dans l'autre.

Donc, en gros, pour un tableau, combien de temps système y a-t-il, voilà en gros ma question.

Et avant que les tableaux ne soient mauvais , l'équipe ne se réveille pas, cette partie de la solution est un type de construction statique, référence unique, souvent, il n'est donc pas nécessaire d'utiliser des listes évolutives.

Était-ce utile?

La solution

Excellente question. J'ai trouvé cet article qui contient des schémas fonctionnels pour les types de valeur et les types de référence. Voir également cet article dans lequel Ritcher déclare:

  

[snip] chaque tableau a quelques informations supplémentaires   informations sur les frais généraux associées à   il. Cette information contient le rang   du tableau (nombre de dimensions),   les limites inférieures pour chaque dimension de   le tableau (presque toujours 0), et le   longueur de chaque dimension. Les frais généraux   contient également le type de chaque élément   dans le tableau.

Autres conseils

Une façon d’examiner cela est de regarder le code dans WinDbg. Donc, vu le code ci-dessous, voyons comment cela apparaît sur le tas.

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

La première chose à faire est de localiser l'instance. Comme je l’ai défini comme local dans Main(), il est facile de trouver l’adresse de l’instance.

À partir de l'adresse, nous pouvons vider l'instance réelle, ce qui nous donne:

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

Cela nous indique qu'il s'agit de notre tableau Int32 avec 10 éléments et une taille totale de 52 octets.

Videons la mémoire où se trouve l'instance.

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  .$@.............

J'ai inséré des crochets pour les 52 octets.

  • Les quatre premiers octets font référence à la table de méthodes au 01309584.
  • Puis quatre octets pour la longueur du tableau.
  • Ce qui suit sont les nombres 0 à 9 (chaque quatre octets).
  • Les quatre derniers octets sont nuls. Je ne suis pas tout à fait sûr, mais je suppose que c'est à cet endroit que la référence au tableau syncblock est stockée si l'instance est utilisée pour le verrouillage.

Éditer: longueur oubliée lors de la première publication.

La liste est légèrement incorrecte car, comme l'indique romkyns, l'instance commence réellement à l'adresse - 4 et le premier champ est le Syncblock.

Excellente question! Je voulais le voir moi-même, et cela me semblait une bonne occasion d’essayer CorDbg.exe ...

Il semble que pour les tableaux de nombres entiers simples, le format est le suivant:

ssssllll000011112222....nnnn0000

où s est le bloc de synchronisation, l la longueur du tableau, puis les éléments individuels. Il semble qu’il y ait finalement un 0 à la fin, je ne sais pas pourquoi.

Pour les tableaux multidimensionnels:

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

Où s est le bloc de synchronisation, t le nombre total d’éléments, l1 la longueur de la première dimension, l2 la longueur de la deuxième dimension, puis deux zéros ?, suivi de tous les éléments de manière séquentielle, et enfin à nouveau un zéro .

Les tableaux d'objets sont traités comme des tableaux d'entiers, le contenu est cette fois-ci une référence. Les tableaux dentelés sont des tableaux d'objets où les références pointent vers d'autres tableaux.

Un objet de tableau doit stocker le nombre de dimensions qu’il a et la longueur de chaque dimension. Il y a donc au moins un élément de données à ajouter à votre modèle

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top