Question Combien de mémoire utilise le pointeur null?


En C # si j'utilise le code suivant

Dictionary<int,object> dictionary = new Dictionary<int, object>();
dictionary.Add(1,null);
dictionary.Add(2,new object());
dictionary[2] = null;

Quelle quantité de mémoire est allouée? chaque objet fait-il référence dans le dictionnaire (dictionnaire [1], dictionnaire [2]) prend une taille de pointeur (32 ou 64 bits) sur le tas? en d'autres termes, lorsque je fais dictionary.Add (1, null), le CLR crée-t-il automatiquement 2 allocations sur le tas, une pour l'int et une pour un pointeur nul?


14
2017-09-27 07:36


origine


Réponses:


Le pointeur null n'alloue pas de mémoire supplémentaire pour stocker quoi que ce soit sur le tas (car il n'y a rien à stocker). Cependant, votre dictionnaire doit stocker le pointeur null lui-même, ce qui prend autant d'espace que tout autre pointeur.

Le fait que chaque appel ajoute de nouvelles allocations (pour stocker le pointeur) dépend de l'implémentation du dictionnaire. Habituellement, il a un tableau interne qui est redimensionné si nécessaire.

Dans votre exemple, je suppose que suffisamment d'espace pour quelques éléments est déjà alloué lors de la création du dictionnaire. Donc, l'addition (1, null) n'allouera plus d'espace.

Mise à jour: le capacité initiale par défaut pour le dictionnaire n'est pas spécifié En .NET 4.0, il commence à 0, de sorte que le premier ajout créera la matrice de stockage.


15
2017-09-27 07:42



En soi, un pointeur nul prendra 4 ou 8 octets, selon qu’il fonctionne en 32 bits ou en 64 bits, comme vous l’avez deviné.

Il peut y avoir plus que cela dans une collection donnée. L'implémentation de Dictionary<TKey, TValue> utilise à la fois un tableau de Entry<TKey, TValue> structures, qui contient deux ints ainsi que la clé et la valeur, ainsi qu'un tableau d'entiers utilisé dans l'indexation dans ce tableau. Par conséquent, même s'il n'y avait pas de "salle croissante" (et il y en a généralement), chaque entrée nécessiterait 20 octets ou 24 octets de mémoire (plutôt que les 8 ou 12 entraînés par la taille de la clé et la valeur). le dictionnaire lui-même (y compris la surcharge de chaque tableau).

D'autres implémentations et autres collections auront d'autres frais généraux. Ils ne peuvent même pas stocker un null pour une entrée nulle. null peut être un moyen utile d'indiquer qu'une valeur n'a pas été écrite, auquel cas une valeur spéciale indiquera une valeur réelle de null (particulièrement utile dans les implémentations de dictionnaires sans verrouillage, où il peut être utile de faire la distinction non seulement entre une valeur non définie et une valeur définie, mais entre une valeur non définie, définie et partiellement définie).

Tout ce que vous pouvez vraiment dire, c'est que cette configuration ajoute une valeur de null A) prend un peu de mémoire et B) ne prend pas la mémoire avec une valeur non nulle qui serait prise par l'objet lui-même. Même B) ne tient pas vraiment, puisque si cet objet était également stocké ailleurs, alors il n’ya pas de coût de mémoire supplémentaire pour avoir une autre référence ailleurs, au-delà de la référence elle-même, ce qui rend le coût réel identique au stockage null.


1
2017-09-27 09:02



Je suppose que oui, car null est une référence. Il pointe vers nulle part, mais vous pouvez le remplacer à chaque fois par une référence d'objet réelle.

Donc, je suppose qu'au moins 2 x 64 bits sont alloués, peut-être que le dictionnaire a besoin d'espace supplémentaire pour lui-même.


0
2017-09-27 07:41