3 Stimmen

Was verursacht meinen C#.NET-Speicherleck in einer Anwendung, die im Leerlauf ist?

Ich versuche, einige Speicherleckprobleme in einer Anwendung zu lösen, und ich hoffe wirklich, dass mir hier jemand Einsichten anbieten kann, die helfen werden. Ich habe den ganzen Tag damit herumgespielt und befürchte, dass ich komplett feststecke.

Die Anwendung, mit der ich Probleme habe, funktioniert anfangs einwandfrei, wird jedoch langsam und möglicherweise sogar abstürzen, wenn sie nach ein paar Stunden Inaktivität verwendet wird. Ich gehe davon aus, dass dies auf ein Art von Speicherleck zurückzuführen ist, das im Laufe der Zeit schlimmer wird. Soweit ich weiß, gibt es keine internen Prozesse, wie z. B. Timer oder endlose Schleifen usw., die das Speicherleck verursachen könnten, aber die Symptome sind reproduzierbar, also ist definitiv etwas im Gange.

Um das herauszufinden, habe ich eine Testversion von .NET Memory Profiler heruntergeladen und installiert. Leider bin ich mir jedoch nicht sicher, wie ich die Ergebnisse, die ich erhalte, interpretieren soll. Soweit ich erkennen kann, sind die Klassen, die für mich am problematischsten erscheinen, Systemklassen wie System.Version und System.Object[]. Ich gehe davon aus, dass der "Datensatz" die Anzahl der unerreichbaren Instanzen und Bytes ist, die vom Profiler gemeldet werden.

Hier sind einige Beispieldaten, ähnlich denen, die ich gesehen habe:

  1. Namespace: System

    • Klassenname: Version
    • Lebende Instanzen...
    • Insgesamt: 2
    • Delta: 0
    • Lebende Bytes...
    • Insgesamt: 48
    • Neu: 48
    • Maximal: 24
    • Delta: 0
    • Unerreichbar...
    • Instanzen: 15.556
    • Bytes: 373.344
  2. Namespace: System

    • Klassenname: Object[]
    • Lebende Instanzen...
    • Insgesamt: 1.198
    • Delta: 0
    • Lebende Bytes...
    • Insgesamt: 117.916
    • Neu: 117.916
    • Maximal: 7.016
    • Delta: 0
    • Unerreichbar...
    • Instanzen: 3.054
    • Bytes: 204.592

Wenn ich das richtig verstehe, sind die zwei größten Probleme, mit denen ich konfrontiert bin, dass ich über 15.000 Instanzen von Assemblyversionen und über 3.000 Objekte habe, die "unerreichbar" sind, obwohl ich zugeben muss, dass ich nicht genau weiß, was mit "unerreichbar" gemeint ist.

Also, meine spezifischen Fragen sind diese:

  • Kann mir jemand sagen, ob ich die Daten des .Net Memory Profilers richtig interpretiere?
  • Wenn ich die Daten richtig interpretiere, was könnte dazu führen, dass meine Anwendung mehr Assembly-Versioneninstanzen und mehr Objektinstanzen erzeugt, während kein Endbenutzer damit interagiert?

5voto

Hans Passant Punkte 894572

Es gibt keine echten Beweise für irgendeine Art von Leckage, basierend auf dem, was du gepostet hast. Der Garbage-Collector wurde seit einiger Zeit nicht mehr ausgeführt, das ist normal bei einem inaktiven Programm. Die 0,5 MB, die diese nicht gesammelten Objekte einnehmen, sind peanuts.

Was passiert, wenn ein Programm eine Weile inaktiv ist, ist, dass seine virtuellen Speicherseiten in die Auslagerungsdatei verschoben werden. Wenn es wieder in den Fokus gelangt, müssen diese Seiten wieder zurück verschoben werden. Bei älteren Maschinen kann das eine Weile dauern. Dein richtiges Problem ist höchstwahrscheinlich die Fragmentierung der Festplatte, besonders der Auslagerungsdatei.

Du solltest es an der Festplattenzugriffsleuchte sehen können, sie sollte hektisch blinken. Du kannst es auch anhand von TaskMgr.exe, dem Register "Prozesse", erkennen. Klicke auf "Ansicht" + "Spalten auswählen" und setze einen Haken bei "Seitenfehler-Delta". Diese Zahl sollte innerhalb einer Sekunde oder weniger auf null gehen, nachdem das Programmfenster wiederhergestellt wurde.

Defragmentiere deine Festplatte. Besonders die Auslagerungsdatei, was schwierig ist. Stelle Fragen dazu auf superuser.com

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