2010-11-15 7 views
10

J'ai une question assez simple sur le stockage des données et son empreinte mémoire..NET Taille de la mémoire

J'ai un List<t> qui stocke les objets de base dont j'ai besoin. Le type t a un identifiant pour le définir, ainsi que d'autres champs.

J'ai maintenant un dictionnaire. Si je crée un Dictionary<t, int>, où t est l'objet de la valeur, l'allocation de mémoire sera-t-elle beaucoup plus élevée si je crée un Dictionary<int, int>, c'est-à-dire qu'une copie de l'objet t est stockée ou seulement une référence pour t stockée?

Merci

+2

Je pense que vous vouliez dire Dictionnaire . La clé est le premier type, la valeur est le deuxième type. –

+0

oui, c'est ce que je voulais dire merci – cab

Répondre

13

Cela dépend de ce que T est. Si T est un type de référence (c'est-à-dire un class), seule une référence sera enregistrée dans le dictionnaire. Si T est un type de valeur (struct), une copie sera stockée.

+4

Bien sûr, la référence pointant vers un objet réel entraîne également une allocation séparée de cet objet réel. –

1

Seule une référence à votre objet est stockée. L'allocation de mémoire sera petite.

5

Les types de référence ne créent pas d'objets en double lorsque vous les passez. Sous les couvertures, vous passez des pointeurs. Donc, si vous avez N objets, vous aurez N x mémoire par objet + la mémoire nécessaire pour référencer chaque objet. C'est indépendamment du conteneur de stockage pour ces références, dans votre cas, un dictionnaire. Vous encourez des frais de mémoire pour le dictionnaire, mais si vous créez un autre dictionnaire et y placez tous les mêmes objets, vous ne disposerez que de 2 coûts de mémoire du dictionnaire plus un ensemble d'objets en mémoire. C'est quand vous utilisez des types de référence.

MyObject object = new MyObject(); // one object created in memory 
MyObject object2 = object; // still only one object created in memory, but we have two references now 

Les types de valeur sont toujours uniques en mémoire. Donc, si vous créez un dictionnaire de System.Int32, puis créez un doublon du dictionnaire, vous aurez également une copie de chaque valeur dans le dictionnaire.

int myInt = 5; // one int created in memory 
int myInt2 = myInt; // two ints have been created in memory 

Donc, nous allons savoir ce que les morceaux de mémoire sont alloués pour certains scénarios:

// two value types 
Dictionary<int, int> myDictionary1 = 
1 x Dictionary 
N x int <key> 
N x int <value> 

Dictionary<int, int> myDictionary1 + 
Dictionary<int,int> myDictionary2 (clone of 1) = 
2 x Dictionary 
2N x int <key> 
2N x int <value> 

// reference types 
Dictionary <string, MyObject> myDictionary3 = 
1 x Dictionary 
N x string Reference 
N x string instance (if they are all unique) 
N x Object Reference 
N x Object instance (if they are all unique) 

Dictionary <string, MyObject> myDictionary3 + 
Dictionary <string, MyObject> MyDictionary4 (clone of 3) = 
2 x Dictionary 
2N x string reference 
1N x string instance (if they are all unique) 
2N x Object reference 
1N x Object instance (if they are all unqiue) 

vous êtes scénario:

Dictionary<int, MyObject> myDictionary5 
1 X Dictionary 
N X key 
N X value reference 
N X value object 

Dictionary<int, MyObject> myDictionary5 + 
Dictionary<int, MyObject> myDictionary6 (clone of 5) = 
2 x Dictionary 
2N x key 
2N x value reference 
1N x value objects 
1

Je suppose que vous parlez du type de collection spécifique System.Collections.Generic.Dictionary<K,V> .

Vous ne nous avez pas dit si votre type 't' est un type de valeur ou un type de référence.

S'il s'agit d'un type de référence, par ex. , puis Dictionary<K,T> conservera les références aux objets que vous avez ajoutés.

S'il s'agit d'un type de valeur, par ex. struct T { int id; ...}, puis Dictionary<K,T> conservera des copies des valeurs que vous avez ajoutées.

Joyeux hacking.

0

Comme je l'ai mentionné dans d'autres questions pour le profilage de la mémoire tout en développant vous pouvez utiliser ce code:

bool forceFullCollection = false; 

Int64 valTotalMemoryBefore = System.GC.GetTotalMemory(forceFullCollection); 

//call here your bulk of Dictionary operations and objects allocations 

Int64 valTotalMemoryAfter = System.GC.GetTotalMemory(forceFullCollection); 

Int64 valDifferenceMemorySize = valTotalMemoryAfter - valTotalMemoryBefore; 

A propos de paramètre forceFullCollection: « Si le paramètre forceFullCollection est vrai, cette méthode attend un court intervalle avant de revenir tandis que le système recueille les ordures et finalise les objets La durée de l'intervalle est une limite spécifiée en interne déterminée par le nombre de cycles de récupération de place terminés et le changement de la quantité de mémoire récupérée entre les cycles. Est collecté." GC.GetTotalMemory Method

Bonne chance !;)

Questions connexes