web-dev-qa-db-fra.com

Comment obtenir la taille d'un objet en mémoire?

J'ai besoin de savoir combien d'octets mon objet consomme en mémoire (en C #). par exemple combien mon Hashtable, ou SortedList, ou List<String>.

188

cela peut ne pas être précis, mais sa assez proche pour moi

long size = 0;
object o = new object();
using (Stream s = new MemoryStream()) {
    BinaryFormatter formatter = new BinaryFormatter();
    formatter.Serialize(s, o);
    size = s.Length;
}
162
Rush Frisby

Je ne pense pas que vous puissiez l'obtenir directement, mais il existe plusieurs façons de le trouver indirectement.

Une méthode consiste à utiliser la méthode GC.GetTotalMemory pour mesurer la quantité de mémoire utilisée avant et après la création de votre objet. Ce ne sera pas parfait, mais tant que vous contrôlerez le reste de l'application, vous obtiendrez peut-être les informations qui vous intéressent.

En dehors de cela, vous pouvez utiliser un profileur pour obtenir les informations ou vous pouvez utiliser le profiling api pour obtenir les informations en code. Mais ce ne sera pas facile à utiliser, je pense.

Voir Découvrez combien de mémoire est utilisée par un objet en C #? pour une question similaire.

107
Rune Grimstad

OK, cette question a reçu une réponse et sa réponse a été acceptée, mais quelqu'un m'a demandé de mettre ma réponse pour vous.

Tout d’abord, il n’est pas possible de le dire avec certitude. C'est un détail d'implémentation interne et non documenté. Cependant, en fonction des objets inclus dans l'autre objet. Maintenant, comment calcule-t-on la mémoire requise pour nos objets mis en cache?

J'avais déjà touché ce sujet dans ce article :

Maintenant, comment calcule-t-on la mémoire requise pour nos objets mis en cache? Comme le savent la plupart d’entre vous, Int32 et float ont quatre octets, double et DateTime 8 octets, char est en fait deux octets (et non un octet), et ainsi de suite. La chaîne est un peu plus complexe, 2 * (n + 1), où n est la longueur de la chaîne. Pour les objets, cela dépend de leurs membres: résumez simplement les besoins en mémoire de tous ses membres, en vous rappelant que toutes les références d'objet sont simplement des pointeurs sur 4 octets sur une zone de 32 bits. Or, ceci n’est en fait pas tout à fait vrai, nous n’avons pas pris en charge les frais généraux de chaque objet du tas. Je ne sais pas si vous devez vous inquiéter à ce sujet, mais je suppose que si vous utilisez beaucoup de petits objets, vous devrez tenir compte des frais généraux. Chaque objet de tas coûte autant que ses types primitifs, plus quatre octets pour les références d'objet (sur une machine 32 bits, bien que BizTalk s'exécute également en 32 bits), plus 4 octets pour le pointeur de type d'objet, et je pense 4 octets pour l'index de bloc de synchronisation. Pourquoi ces frais généraux supplémentaires sont-ils importants? Eh bien, imaginons que nous ayons une classe avec deux membres Int32; dans ce cas, la mémoire requise est de 16 octets et non de 8.

26
Aliostad

Objet non géré:

  • Marshal.SizeOf(object yourObj);

Types de valeur:

  • sizeof(object val)

Objet géré:

26
NileshChauhan

Le fragment de code suivant doit renvoyer la taille en octets de tout objet qui lui est transmis, tant qu'il peut être sérialisé. C'est ce que m'a demandé un collègue de Quixant pour résoudre un problème d'écriture sur SRAM sur une plate-forme de jeu. J'espère que ça aide. Crédit et merci à Carlo Vittuci.

/// <summary>
/// Calculates the lenght in bytes of an object 
/// and returns the size 
/// </summary>
/// <param name="TestObject"></param>
/// <returns></returns>
private int GetObjectSize(object TestObject)
{
    BinaryFormatter bf = new BinaryFormatter();
    MemoryStream ms = new MemoryStream();
    byte[] Array;
    bf.Serialize(ms, TestObject);
    Array = ms.ToArray();
    return Array.Length;
}
16
Kevin Hirst

En mode débogage

charger SOS

et exécutez la commande dumpheap.

0
A.m.a.L