Ich habe 10 Jahre lang C ++ geschrieben. Ich habe Speicherprobleme festgestellt, die jedoch mit vertretbarem Aufwand behoben werden konnten.
In den letzten Jahren habe ich C # geschrieben. Ich finde, ich bekomme immer noch viele Gedächtnisprobleme. Sie sind aufgrund der Nichtbestimmtheit schwer zu diagnostizieren und zu beheben, und weil die C # -Philosophie lautet, dass Sie sich über solche Dinge keine Sorgen machen sollten, wenn Sie dies auf jeden Fall tun.
Ein besonderes Problem ist, dass ich alles im Code explizit entsorgen und bereinigen muss. Wenn ich das nicht tue, helfen die Speicherprofiler nicht wirklich, weil so viel Spreu um Sie herum schwebt. Sie können kein Leck in allen Daten finden, die sie Ihnen zeigen wollen. Ich frage mich, ob ich die falsche Idee habe oder ob das Werkzeug, das ich habe, nicht das beste ist.
Welche Strategien und Tools sind nützlich, um Speicherlecks in .NET zu beheben?
quelle
Antworten:
Ich verwende den MemProfiler von Scitech, wenn ich einen Speicherverlust vermute.
Bisher habe ich festgestellt, dass es sehr zuverlässig und leistungsstark ist. Es hat meinen Speck bei mindestens einer Gelegenheit gerettet.
Der GC funktioniert in .NET IMO sehr gut, aber genau wie in jeder anderen Sprache oder Plattform passieren schlechte Dinge, wenn Sie schlechten Code schreiben.
quelle
Probieren Sie die in diesem Blogbeitrag beschriebene Lösung aus , um das Problem des Vergessens zu vergessen . Hier ist die Essenz:
quelle
Wir haben in unserem Projekt die Software Ants Profiler Pro von Red Gate verwendet. Es funktioniert sehr gut für alle sprachbasierten .NET-Anwendungen.
Wir haben festgestellt, dass der .NET Garbage Collector bei der Bereinigung von In-Memory-Objekten (wie es sein sollte) sehr "sicher" ist. Es würde Objekte in der Nähe halten, nur weil wir es möglicherweise irgendwann in der Zukunft verwenden werden. Dies bedeutete, dass wir bei der Anzahl der Objekte, die wir im Speicher aufgeblasen hatten, vorsichtiger sein mussten. Am Ende haben wir alle unsere Datenobjekte in ein "Inflate-on-Demand" konvertiert (kurz bevor ein Feld angefordert wird), um den Speicheraufwand zu reduzieren und die Leistung zu steigern.
EDIT: Hier ist eine weitere Erklärung dessen, was ich unter "Inflate on Demand" verstehe. In unserem Objektmodell unserer Datenbank verwenden wir Eigenschaften eines übergeordneten Objekts, um die untergeordneten Objekte verfügbar zu machen. Wenn wir beispielsweise einen Datensatz hätten, der eins zu eins auf einen anderen "Detail" - oder "Lookup" -Datensatz verweist, würden wir ihn folgendermaßen strukturieren:
Wir haben festgestellt, dass das oben genannte System einige echte Speicher- und Leistungsprobleme verursacht hat, wenn sich viele Datensätze im Speicher befinden. Deshalb haben wir auf ein System umgestellt, bei dem Objekte nur dann aufgeblasen wurden, wenn sie angefordert wurden, und Datenbankaufrufe nur bei Bedarf durchgeführt wurden:
Dies stellte sich als viel effizienter heraus, da Objekte nicht gespeichert wurden, bis sie benötigt wurden (auf die Get-Methode wurde zugegriffen). Es bot eine sehr große Leistungssteigerung bei der Begrenzung von Datenbanktreffern und einen enormen Gewinn an Speicherplatz.
quelle
Sie müssen sich immer noch Gedanken über den Speicher machen, wenn Sie verwalteten Code schreiben, es sei denn, Ihre Anwendung ist trivial. Ich werde zwei Dinge vorschlagen: Lesen Sie zuerst CLR über C #, da dies Ihnen hilft, die Speicherverwaltung in .NET zu verstehen. Zweitens lernen Sie, ein Tool wie CLRProfiler (Microsoft) zu verwenden. Dies kann Ihnen eine Vorstellung davon geben, was Ihren Speicherverlust verursacht (z. B. können Sie einen Blick auf die Fragmentierung Ihres großen Objekthaufens werfen).
quelle
Verwenden Sie nicht verwalteten Code? Wenn Sie laut Microsoft keinen nicht verwalteten Code verwenden, sind Speicherverluste im herkömmlichen Sinne nicht möglich.
Der von einer Anwendung verwendete Speicher wird jedoch möglicherweise nicht freigegeben, sodass die Speicherzuordnung einer Anwendung während der gesamten Lebensdauer der Anwendung zunehmen kann.
Um diese Art von Problem zu lösen , können Sie IDisposable implementieren . Wenn Sie einige der Strategien für den Umgang mit Speicherverwaltung sehen möchten, würde ich vorschlagen, nach IDisposable, XNA und Speicherverwaltung zu suchen, da Spieleentwickler eine vorhersehbarere Speicherbereinigung benötigen und den GC daher zwingen müssen, seine Aufgabe zu erledigen.
Ein häufiger Fehler besteht darin, Ereignishandler, die ein Objekt abonnieren, nicht zu entfernen. Ein Event-Handler-Abonnement verhindert, dass ein Objekt recycelt wird. Schauen Sie sich auch die using- Anweisung an, mit der Sie einen begrenzten Bereich für die Lebensdauer einer Ressource erstellen können.
quelle
Dieser Blog enthält einige wirklich wundervolle exemplarische Vorgehensweisen, bei denen Windbg und andere Tools verwendet werden, um Speicherlecks aller Art aufzuspüren. Hervorragende Lektüre, um Ihre Fähigkeiten zu entwickeln.
quelle
Ich hatte gerade einen Speicherverlust in einem Windows-Dienst, den ich behoben habe.
Zuerst habe ich MemProfiler ausprobiert . Ich fand es sehr schwer zu bedienen und überhaupt nicht benutzerfreundlich.
Dann habe ich JustTrace verwendet, das einfacher zu verwenden ist und Ihnen mehr Details zu den Objekten gibt, die nicht richtig angeordnet sind.
Dadurch konnte ich das Speicherleck sehr einfach beheben.
quelle
Wenn die beobachteten Lecks auf eine außer Kontrolle geratene Cache-Implementierung zurückzuführen sind, ist dies ein Szenario, in dem Sie möglicherweise die Verwendung von WeakReference in Betracht ziehen sollten. Dies kann dazu beitragen, dass bei Bedarf Speicher freigegeben wird.
Meiner Meinung nach ist es jedoch besser, eine maßgeschneiderte Lösung in Betracht zu ziehen - nur Sie wissen wirklich, wie lange Sie die Objekte in der Nähe halten müssen. Daher ist das Entwerfen eines geeigneten Housekeeping-Codes für Ihre Situation normalerweise der beste Ansatz.
quelle
Ich bevorzuge Dotmemory von Jetbrains
quelle
Big Guns - Debugging-Tools für Windows
Dies ist eine erstaunliche Sammlung von Werkzeugen. Sie können damit sowohl verwaltete als auch nicht verwaltete Heaps analysieren und offline ausführen. Dies war sehr praktisch für das Debuggen einer unserer ASP.NET-Anwendungen, die aufgrund von Speicherüberlastung weiterhin recycelt wurden. Ich musste nur einen vollständigen Speicherauszug des lebenden Prozesses erstellen, der auf dem Produktionsserver ausgeführt wurde. Alle Analysen wurden offline in WinDbg durchgeführt. (Es stellte sich heraus, dass einige Entwickler den In-Memory-Sitzungsspeicher überlasteten.)
"Wenn kaputt ist es ..." Blog hat sehr nützliche Artikel zu diesem Thema.
quelle
Das Beste, was Sie beachten sollten, ist, die Verweise auf Ihre Objekte zu verfolgen. Es ist sehr einfach, Verweise auf Objekte aufzuhängen, die Sie nicht mehr interessieren. Wenn Sie etwas nicht mehr verwenden, entfernen Sie es.
Gewöhnen Sie sich daran, einen Cache-Anbieter mit verschiebbaren Ablaufzeiten zu verwenden, damit etwas, auf das für ein gewünschtes Zeitfenster nicht verwiesen wird, dereferenziert und bereinigt wird. Wenn jedoch häufig darauf zugegriffen wird, wird dies im Speicher angezeigt.
quelle
Eines der besten Tools ist die Verwendung der Debugging-Tools für Windows und die Erstellung eines Speicherauszugs des Prozesses mithilfe von adplus . Anschließend können Sie mithilfe von windbg und dem sos- Plugin den Prozessspeicher, die Threads und die Aufrufstapel analysieren.
Sie können diese Methode verwenden, um Probleme auch auf Servern zu identifizieren. Nachdem Sie die Tools installiert haben, geben Sie das Verzeichnis frei, stellen Sie dann mithilfe von (Net Use) eine Verbindung zur Freigabe vom Server her und führen Sie entweder einen Absturz oder einen Hang-Dump des Prozesses durch.
Dann offline analysieren.
quelle
Nach einem meiner Fixes für verwaltete Anwendungen hatte ich das gleiche Problem, wie ich überprüfen konnte, ob meine Anwendung nach meiner nächsten Änderung nicht denselben Speicherverlust aufweist. Ich habe also so etwas wie das Framework zur Überprüfung der Objektfreigabe geschrieben. Schauen Sie sich das an das NuGet-Paket ObjectReleaseVerification . Ein Beispiel finden Sie hier https://github.com/outcoldman/OutcoldSolutions-ObjectReleaseVerification-Sample und Informationen zu diesem Beispiel http://outcoldman.ru/en/blog/show/322
quelle
In Visual Studio 2015 sollten Sie ein sofort einsatzbereites Diagnosetool für die Speichernutzung verwenden, um Daten zur Speichernutzung zu erfassen und zu analysieren.
Mit dem Tool zur Speichernutzung können Sie einen oder mehrere Snapshots des verwalteten und nativen Speicherheaps erstellen, um die Auswirkungen der Objektnutzung auf die Speichernutzung zu verstehen.
quelle
Eines der besten Tools, das ich mit DotMemory verwendet habe. Sie können dieses Tool als Erweiterung in VS verwenden. Nachdem Sie Ihre App ausgeführt haben, können Sie jeden Teil des Speichers (nach Objekt, NameSpace usw.) analysieren, den Ihre App verwendet, und einen Schnappschuss davon erstellen Vergleichen Sie es mit anderen SnapShots. DotMemory
quelle