Was ist das "pinning handle object []", das ich in Jetbrains dotMemory sehe, wenn ich eine ListT verwende?

8

Ich habe versucht, den einfachsten Code zu finden, um zu reproduzieren, was ich sehe. Das vollständige Programm ist unten, aber ich werde es hier beschreiben. Angenommen, ich habe die Klasse ListData , die nur einige Eigenschaften hat. Dann nehme ich an, dass ich eine Klasse MyList mit einem Mitglied List<ListData> m_list habe. Angenommen, m_list wird im Konstruktor MyList initialisiert.

In der Hauptmethode erzeuge ich einfach eines dieser MyList -Objekte, füge ein paar ListData hinzu und lasse es dann außerhalb des Bereichs liegen. Ich mache einen Schnappschuss in dotMemory, nachdem die ListData hinzugefügt wurden, dann nehme ich einen weiteren Schnappschuss, nachdem das Objekt MyList den Gültigkeitsbereich verlassen hat.

In dotMemory kann ich sehen, dass das Objekt MyList wie erwartet zurückgefordert wurde. Ich sehe auch, dass die zwei ListData -Objekte, die ich erstellt habe, auch wie erwartet zurückgefordert wurden.

Was ich nicht verstehe, warum gibt es ein ListData[] , das überlebt hat? Hier ist ein Screenshot von diesem:

Ich öffne überlebte Objekte auf dem neuesten Snapshot für die ListData[] , dann sehe ich Key Retention Paths, das ist was ich sehe.

Ich bin neu in der .NET-Speicherverwaltung und habe diese Beispiel-App erstellt, die mir hilft, sie zu erkunden. Ich habe die Testversion von JetBrains dotMemory Version 4.3 heruntergeladen. Ich verwende Visual Studio 2013 Professional. Ich muss Speicherverwaltung lernen, damit ich die Speicherprobleme beheben kann, die wir bei der Arbeit haben.

Hier ist das vollständige Programm, das verwendet werden kann, um dies zu reproduzieren. Es ist nur eine schnelle und dreckige App, aber es wird das bekommen, wonach ich frage, wenn Sie es profilieren.

%Vor%

Schritte:

  1. Erstellen Sie obigen Code in Version.
  2. Wählen Sie in dotMemory, um ein Profil zu erstellen eigenständige App
  3. Navigieren Sie zur Release-Exe.
  4. Wählen Sie die Option zum sofortigen Sammeln von Zuordnungsdaten.
  5. Klicken Sie auf Ausführen.
  6. Machen Sie sofort einen Schnappschuss und nennen Sie ihn "vorher". Dies ist vor jedem ListData wurden hinzugefügt.
  7. Geben Sie in der App a ein und fügen Sie zwei ListData hinzu.
  8. In dotMemory, nimm einen anderen Snapshot und nenne ihn "added 2" weil wir     zwei ListData hinzugefügt.
  9. Geben Sie in der App q ein, um den Vorgang abzubrechen (die MyList wird den Gültigkeitsbereich verlassen). Bevor Sie die Eingabe erneut eingeben, um die App zu beenden, machen Sie einen weiteren Schnappschuss in dotMemory. Nennen Sie es "außerhalb des Geltungsbereichs".
  10. Geben Sie in der App die Eingabetaste ein, um die App zu schließen.
  11. Vergleichen Sie in dotMemory die "addierte 2" und die "außerhalb des Bereichs"  Schnappschüsse. Nach Namespace gruppieren. Sie sehen die ListData [], auf die ich mich beziehe.

Beachten Sie, dass die MyList-Objekte und die zwei ListData-Objekte eine Speicherbereinigung erhielten, die ListData [] jedoch nicht. Warum hängt ein ListData [] herum? Wie kann ich dafür sorgen, dass Müll gesammelt wird?

    
cchampion 06.07.2015, 00:56
quelle

1 Antwort

3
  

Warum hängt ein ListData [] herum? Wie kann ich es schaffen?   Müll gesammelt?

Wenn Sie den "Creation Stack Trace" in dotMemory betrachten, sehen Sie:

Dies zeigt Ihnen, dass die leere ListData[0] Instanz über den statischen Konstruktor von List<T> erstellt wurde. Wenn Sie sich die Quelle ansehen , sehen Sie Folgendes:

%Vor%

List<T> initialisiert ein leeres Standard-Array, um die Vermeidung einer solchen Zuweisung jedes Mal zu optimieren, wenn Sie ein neues List<T> erstellen. Dies ist der Standardkonstruktor:

%Vor%

Wenn Sie nur List<T>.Add verwenden, ändert sich die Größe des Arrays.

static -Member werden aus "High Frequency Heap" referenziert, die einmal für erstellt wurden jedes AppDomain in Ihrer Anwendung. Das gepinnte object[] , das Sie sehen, ist der Ort, an dem alle static Instanzen gespeichert sind.

Da die Instanz static ist, bleibt sie für die gesamte Lebensdauer Ihrer Anwendung im Speicher.

    
Yuval Itzchakov 06.07.2015, 07:29
quelle

Tags und Links