7 Stimmen

Wo ist mein Speicher geblieben? große private Bytes-Anzahl

Ich habe eine WPF-App, die unter anderem viele Bilder in verschiedenen Größen anzeigt. Mein Problem ist, dass die App viel Speicher verbraucht und ich nicht herausfinden kann, woher das kommt.

Das Szenario, wenn die App etwas belastet wird, führt zu diesem Diagramm in Perfmon:

http://www.imagechicken.com/uploads/1244548604007097000.jpg

Die dicke schwarze Linie zeigt Process\Private Bytes und die anderen Linien sind die CLR-Speicherzähler (die pinke zeigt die insgesamt reservierten Bytes)

In Zahlen im Diagramm sind:
Private Bytes ~ 350 Mb
Committed Bytes ~ 100 Mb

Ich habe viel mit WinDbg und anderen Tools herumgegraben, und sie alle zeigen, dass der verwaltete Stapel sich normal verhält (insgesamt verwalteter Stapel von ca. 100 Mb gemäß !eeheap-Berichten)

Ich habe mit Apps wie LeakDiag und LDGrapher herumexperimentiert, aber nichts gefunden.

Also, schlussendlich meine Frage, wie gehe ich am besten vor, um herauszufinden, wohin mein Speicher verschwindet?

Schon beim Start der App werden 100 MB in reservierten Bytes und 190 MB in privaten Bytes verwendet.

Verweise:

Ich habe viel darüber gelesen, unter anderem auf den großartigen Seiten von:

Tess Ferrandez: http://blogs.msdn.com/tess/archive/2009/02/27/net-memory-leak-reader-email-are-you-really-leaking-net-memory.aspx

Rico Mariani: http://blogs.msdn.com/ricom/archive/2004/12/10/279612.aspx

MSDN mag: http://msdn.microsoft.com/en-us/magazine/cc163528.aspx

4voto

Bradley Grainger Punkte 25874

Ich hatte ein ähnliches Problem in einer WPF-Anwendung und habe UMDH verwendet, um zu verfolgen, wo der native Speicher allokiert wurde. (Beachten Sie, dass es normalerweise hilfreich ist, _NT_SYMBOL_PATH zu setzen, um gute Stapelüberläufe von den Betriebssystemkomponenten zu erhalten.)

Die Protokolle zeigten, dass fast der gesamte Speicher im Grafiktreiber allokiert wurde. Ich stellte fest, dass der Treiber mehr als ein Jahr veraltet war; ich installierte die neueste Version von der Website des Herstellers und das löste das Problem.

3voto

Brian Rasmussen Punkte 112118

Nur weil Ihre Anwendung viel Speicher verwendet, bedeutet dies nicht zwangsläufig, dass Sie einen Speicherleck haben. Aus den Informationen in Ihrer Frage ist es schwer zu sagen, was vielleicht falsch ist.

Beim Beheben von verwalteten Speicherlecks mit WinDbg mache ich folgendes:

  • Bekommen Sie einen Überblick über die Heapsnutzung mit !eeheap (dies zeigt die Heapsnutzung an und nicht den Stack, den Sie erwähnen - jeder Stack hat eine Standardgröße von 1 MB, also, es sei denn, Sie haben dies geändert, gibt es keine Möglichkeit, 100 MB auf dem Stack zu verwenden)

  • Führen Sie ein !dumpheap -stat durch, um herauszufinden, was sich auf dem Heap befindet. Wahrscheinlich werden, wenn Sie ein Speicherleck haben, die schuldigen Typen unter den Top-Verbrauchern liegen. Um eine Vorstellung davon zu bekommen, wie sich die Heapsnutzung entwickelt, können Sie Ihre Anwendung fortsetzen, sie später beenden und dann das Befehl !dumpheap -stat wiederholen.

  • Wenn Sie Typen mit mehr Instanzen finden als Sie erwarten würden, listen Sie diese mit !dumpheap -mt auf. Dies listet alle Instanzen des bestimmten Typs auf. Wählen Sie zufällige Instanzen aus und überprüfen Sie die Referenzen mit dem Befehl !gcroot. Dadurch erfahren Sie, was die betreffenden Instanzen am Leben hält. Ohne Wurzeln werden diese Instanzen irgendwann gesammelt.

UPDATE zur Beantwortung Ihrer Kommentare:

Der verwaltete Heap ist nur ein Teil des Speicher-Fußabdrucks einer verwalteten Anwendung. Bedenken Sie, dass eine .NET-Anwendung wirklich eine Anwendung in einer anderen Anwendung ist - dem Hostprozess, der die CLR lädt, die wiederum Ihre Anwendung lädt. Bevor Ihre Anwendung also irgendwelchen Speicher verwendet, hat die CLR bereits einen recht großen Anteil genommen. Darüber hinaus speichern .NET-Anwendungen sowohl MSIL-Code als auch JIT-kompilierten Code als Teil des Fußabdrucks. Die CLR benötigt auch Platz für verschiedene Verwaltungsaufgaben (z. B. die CLR erstellt zwei zusätzliche AddDomains für den internen Gebrauch).

Die von Ihnen genannten Zahlen erscheinen mir nicht übertrieben, aber da ich Ihre Anwendung nicht kenne, ist es schwer zu sagen, ob sie übermäßig sind.

100 MB auf dem verwalteten Heap könnte in Ordnung sein, abhängig davon, was Ihre Anwendung tut. Haben Sie den Heap überprüft? Und wenn ja, was haben Sie gefunden?

1voto

Mitch Wheat Punkte 287474

Laden Sie MemProfiler von Scitech herunter. Es gibt eine 14-tägige Testversion.

Das von Ihnen gemeldete Problem ist oft auf Ansichten/Ressourcen zurückzuführen, die aufgrund einer Verbindung mit dem Heap nicht freigegeben werden können. Eine häufige Ursache ist das Nicht-Entfernen von Ereignishandlern.

1voto

Drew Noakes Punkte 282438

Sie könnten versuchen, diesen Artikel im neuesten MSDN-Magazin zu lesen. Er geht ins Detail darüber, wie man VADump verwenden kann, um mehr darüber zu erfahren, wo der Speicher eines Prozesses verwendet wird.

Sie können VADump hier herunterladen: http://go.microsoft.com/fwlink/?LinkId=149683

Um den verwalteten Heap aufzuschlüsseln, könnten Sie einen Speicherprofiler ausprobieren. Ich persönlich mag JetBrains dotTrace.

0voto

andyhammar Punkte 1415

Eine Antwort: Es geht zu viel zu viele zusammengeführte ResourceDictionaries (eine WPF-Sache)

Details: Um das Design zur Entwurfszeit in Blend und VS sehen zu können, pflegten wir, unser Designressourcen-Dictionary auf den meisten XAML-Seiten zusammenzuführen. Dadurch wurde eine Kopie aller Ressourcen für jedes Steuerelement geladen, weitere Informationen können hier gelesen werden: [WPF Disciples]

Also der einzige Ort, an dem ich sie jetzt zusammenführe, ist App.xaml.cs:

Ergebnisse: (Ausführen der App durch einige Seiten mit einem automatischen GUI-Test)

Vorher:

  • Nach dem App-Start: 63 Mb
  • Nach der App-Nutzung: 177 Mb

Nachher:

  • Nach dem App-Start: 53 Mb
  • Nach der App-Nutzung: 97 Mb

Ich werde weitere Antworten posten, wenn ich sie finde! (Ich dachte, es wäre am einfachsten für die Leser, meine Entdeckungen als separate Antworten zu sehen, anstatt als Antworten auf Kommentare - gut?)

[1]: ref: http://groups.google.com/group/wpf-disciples/web/wpf-and-xaml-coding-guidelines?pli=1

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X