Wie identifiziere ich, wo Instanzen eines Objekts noch referenziert werden?

8

Nachdem ich den VS2010 Profiler mit Object Lifetime Tracking in meiner App ausgeführt habe, habe ich dies in einer bestimmten Klasse:

Anzahl der Instanzen ---------- 1 418 276
% Gesamtinstanzen ---------------------% 5.8
Gesamtzahl der zugewiesenen Bytes ------- 158 846 912
% Gesamtbytes --------------------------% 5.94
Gen 0 Instances Collected --------- 5 196
Gen 1 Instanzen gesammelt -------- 54 894
Gen 2 Instanzen gesammelt ---- 747 874
Instanzen sind am Ende lebendig --------- 610 312
Gen 0 Bytes gesammelt ----------- 581 952
Gen 1 Bytes gesammelt --------- 6 148 128
Gen 2 Bytes gesammelt --------- 3 761 888

Wie Sie sehen können, enden die Hälfte aller erstellten Instanzen hauptsächlich als Gen 2 , und bleibt die andere Hälfte bis zum Ende der App am Leben [ ha, ha, ha, ha, am Leben bleiben, am Leben bleiben ... - & gt; Ok Entschuldigung, ich könnte nicht widerstehen ... ]

Was mich stört ist, dass diese Instanzen eine sehr kurze Lebensdauer haben sollten (es ist im Grunde eine Datenfeldklasse - das könnte eine Struktur sein, aber ich zog es vor, es zu einer Klasse zu machen, um GC darauf "zu aktivieren").
Diese Instanzen werden erstellt, indem sehr große Binärdateien (jede Zeile ist eine Klasse / ein Datensatz) gelesen und über eine kleine Warteschlange von delegate / event an Worker übergeben werden, die sie im Grunde nur lesen, in Warteschlangen (die sehr regelmäßig aus der Warteschlange genommen und dann beendet (Hintergrundarbeiter enden normal). Ich schätze Ereignisse werden abbestellt, wenn Arbeiter nicht mehr existieren.

Also, gibt es eine Möglichkeit zu identifizieren, wo sich diese Referenzen verbergen ? Denn wenn sie nicht gecodiert werden, werden sie immer noch irgendwo referenziert, aber wie kann man das sicher sagen? Ich bin es leid, so viele Hypothesen zu erraten und zu versuchen, SO, wenn jemand rationellere Richtlinien oder eine faire Checkliste und / oder Werkzeuge / präzise Profiler-Orte zum Anschauen hat, ich begrüße es.

Ergänzende Ressourcen zu den Antworten
Visual GCRoot via DGML - Danke an Richard Szalay
Auch dieses Video GCRoot Demo von Chris Lovett ist sehr lehrreich zu diesem Thema.

    
Mehdi LAMRANI 28.04.2011, 12:45
quelle

2 Antworten

6
  1. Aktivieren Sie das nicht verwaltete Debugging auf der Registerkarte "Debug" Ihrer Projekteigenschaften
  2. Führen Sie die Anwendung aus, und legen Sie einen Haltepunkt an einem Punkt fest, an dem Sie die Typen
  3. untersuchen möchten
  4. Geben Sie im Fenster sofort Folgendes ein:
%Vor%

Dies wird etwas wie folgt zurückgeben:

%Vor%

Dann kannst du Address nehmen und GCRoot verwenden, um den Ort zu finden, an dem es verwurzelt ist:

%Vor%

Chris Lovett (über < a href="http://blogs.msdn.com/b/tess/archive/2010/03/03/tool-for-generating-dgml-graphs-showing-why-your-object-can-t-be- collected-visualgcroot.aspx "> Tess Ferrandez ) hat ein sehr ordentliches Dienstprogramm erstellt, das die Low-Level-Ausgabe GCRoot in ein DGML-Diagramm umwandelt, das die Diagnose erleichtern könnte.

Alternativ hat Mohamed Mahmoud eine Debugger-Erweiterung das ermöglicht Ihnen, das Diagramm von WinDBG zu erzeugen, aber es funktioniert nicht innerhalb von Visual Studio, also möchten Sie möglicherweise Chris 'Dienstprogramm beibehalten, um die Installation der Debugging-Tools zu vermeiden.

Nachdem dies gesagt wurde, kann die Textausgabe ausreichen, um Dinge zu verfolgen. Wenn Sie Informationen zur Ausgabe von GCRoot wünschen, geben Sie !help GCRoot im unmittelbaren Fenster ein.

    
Richard Szalay 28.04.2011, 13:06
quelle
1

Wenn Sie genau wissen wollen, welche Instanzen am Leben sind, müssen Sie nur einen Prozess-Dump mit Adplus machen, der mit dem Debugging-Tools für Windows . (Es ist jetzt Teil des SDK-Downloads.)

Verwenden Sie in WinDBG den! dumpheap-Typ Befehl, um zu sehen, welche Instanzen welcher Klassen noch aktiv sind.

Dann können Sie den! gcroot verwenden, um zu sehen, wer diese Referenz hält.

    
Menahem 28.04.2011 13:02
quelle

Tags und Links