it-swarm.com.de

Ermitteln Sie die Größe eines .net-Objekts

Ich versuche herauszufinden, wie viel Speicher meine Objekte benötigen, um zu sehen, wie viele davon auf dem Large Object Heap landen (was mehr als 85.000 Byte ist).

Ist es so einfach wie das Hinzufügen von 4 für ein int, 8 für ein langes, 4 (oder 8 für 64-Bit) für beliebige Referenztypen usw. für jedes Objekt oder gibt es Overheads für Methoden, Eigenschaften usw.

52

Vergessen Sie nicht, dass die Größe eines tatsächlichen Objekts nicht die Größe von Objekten enthält, auf die es verweist.

Die einzigen Dinge, die wahrscheinlich auf dem großen Objekthaufen landen, sind Arrays und Strings - andere Objekte sind an sich relativ klein. Sogar ein Objekt mit beispielsweise 10 Referenztypvariablen (jeweils 4 Bytes bei x86) und 10 GUIDs (jeweils 16 Bytes) beansprucht nur etwa 208 Bytes (es gibt etwas Overhead für den Typreferenz- und Synchronisationsblock).

Wenn Sie über die Größe eines Arrays nachdenken, vergessen Sie nicht, dass der Elementtyp nur ein Referenztyp ist. Dann zählt nur die Größe der Referenzen für das Array selbst. Mit anderen Worten, selbst wenn Sie ein Array mit 20.000 Elementen haben, wird die Größe des Array-Objekts selbst nur etwas mehr als 80 KB (auf x86) betragen, selbst wenn es auf viel mehr Daten verweist.

50
Jon Skeet

Bitte befolgen Sie diese Schritte, um die Größe des Objekts zu ermitteln.

1) Gehen Sie zu Visual Studio (2010) - Projekteigenschaften -> Registerkarte Debuggen -> Debuggen von nicht verwaltetem Code aktivieren.

2) Gehen Sie zum Menü Debugging von Visual Studio -> Option und Einstellungen -> Debugging -> Symbole.

3) Wenn Sie Microsoft Symbol Server aktivieren, belassen Sie die Standardeinstellung (Symbole können den Download starten.)

4) Legen Sie den Haltepunkt in Ihrem Code fest und beginnen Sie mit dem Debuggen (F5).

5) Öffnen Sie Debug -> Windows -> Direktfenster.

6) Geben Sie .load sos.dll (Son of Strike) ein.

7) Geben Sie! DumpHeap-Typ MyClass ein (das Objekt, dessen Größe Sie ermitteln möchten).

8) Suchen Sie aus dem Ausgabepunkt die Adresse des Objekts, d. H. (00a8197c).

Adresse MT Größe 00a8197c 00955124 36

9) Als nächstes! ObjSize 00a8197c

10) Da gehst du -> sizeof (00a8197c) = 12 (0x48) Bytes (MyClass)

35
Gomes

Sie befinden sich in einem Bereich des fortgeschrittenen .NET-Debugging. Beginnen Sie mit John Robins debuggen Bücher .

Verwenden Sie WinDBG mit Sos.dll (Teil der .NET-Verteilung) und Sosex.dll Erweiterungen. Mit diesen Tools können Sie wirklich sehen, was passiert, wenn Ihre Anwendung ausgeführt wird. Sie finden Antworten auf Ihre oben genannten Fragen.

(Eine weitere Empfehlung wäre die Installation von Shared Source CLI 2.0 , auch Rotor 2 genannt, um zu sehen, was unter der Haube passiert.)

9
David Pokluda

Wenn Sie können - Serialisieren Sie es!

Dim myObjectSize As Long

Dim ms As New IO.MemoryStream
Dim bf As New Runtime.Serialization.Formatters.Binary.BinaryFormatter()
bf.Serialize(ms, myObject)
myObjectSize = ms.Position
9
serhio

Gomes-Methode vereinfacht:

  1. wechseln Sie zu Projekteigenschaften von Visual Studio (2010) -> Registerkarte Debuggen -> Debuggen von nicht verwaltetem Code aktivieren.

  2. Legen Sie den Haltepunkt in Ihrem Code fest und beginnen Sie mit dem Debuggen (F5).

  3. Öffnen Sie Debug -> Windows -> Direktfenster.

  4. geben Sie .load sos ein

  5. geben Sie ein (ersetzen Sie myObject durch den Namen Ihres Objekts) 

. String.Format ("{0: x}", Integer.Parse (System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject (System.Runtime.InteropServices.GCHandle.Alloc (myObject). GetHandleValue ()). )) - 4)

6. Verwenden Sie result als Parameter von! ObjSize

siehe: SOS.DLL, Objektadresse und Visual Studio-Debugger Einführung

Beispiel (wir suchen nach dem Objekt tbl):

.load sos
extension C:\Windows\Microsoft.NET\Framework\v4.0.30319\sos.dll loaded
? string.Format("{0:x}",Integer.Parse(System.Runtime.InteropServices.GCHandle.InternalAddrOfPinnedObject(System.Runtime.InteropServices.GCHandle.Alloc(tbl).GetHandleValue()).ToString())-4)
"27ccb18"
!ObjSize 27ccb18
PDB symbol for clr.dll not loaded
sizeof(027ccb18) =       154504 (     0x25b88) bytes (System.Data.DataTable)
5
IvanH

Wenn es sich nicht um einen großen Werttyp oder Instanztyp (d. H. Viele Tausende von Feldern) handelt, müssen Sie sich nur um große Arrays oder Strings kümmern. Um die Größe eines Arrays herauszufinden, müssen Sie natürlich die Elementgröße kennen.

.NET richtet (derzeit) Typen auf die gleiche Weise aus, wie native Compiler Typen ausrichten. Grundtypen haben natürliche Ausrichtungen, die in der Regel die aufgerundete integrale Kraft von zwei sind, die ihrer Größe am nächsten ist:

Single, Int32, UInt32 - 4
IntPtr, UIntPtr, pointers, references  - 4 on 32-bit, 8 on 64-bit
Double, Int64, UInt64 - 8
Char, Int16, UInt16   - 2
Byte, SByte           - 1

Beim Zusammenstellen eines Typs stellt der Compiler sicher, dass der Startversatz aller Felder eines bestimmten Typs innerhalb der Instanz an einer diesem Typ entsprechenden Grenze ausgerichtet ist. Dabei wird davon ausgegangen, dass kein explizites Layout verwendet wird.

Benutzerdefinierte Typen haben selbst eine Ausrichtung, die als höchste Ausrichtung eines ihrer Feldtypen berechnet wird. Die Größe des Typs wird bei Bedarf erweitert, um auch die Größe des Typs anzupassen.

Natürlich haben alle Referenztypen immer noch nur die Größe und Ausrichtung von IntPtr.Size, daher wirkt sich die Größe des Referenztyps nicht auf Arrays dieses Typs aus.

Man beachte, dass die CLR nach eigenem Ermessen zwischen den Layouttypen wählen kann, die anders als oben beschrieben sind, um möglicherweise die Cache-Lokalität zu erhöhen oder das durch die Ausrichtung erforderliche Auffüllen zu reduzieren.

4
Barry Kelly

Als Schätzwert (für 2017) können Sie ein Debugging in Ihre Anwendung durchführen, einen Haltepunkt festlegen, bevor Ihr Wörterbuch aktiviert wird, einen "Speicherbelegungs-Snapshot" (Registerkarte: Speicherbelegung unter Diagnosetools) erstellen, Ihr Wörterbuch füllen und einen weiteren Snapshot erhalten - nicht Genau gesagt, eine gute Gebärde.

0
Patrick Artner