Anatomie eines "Memory Leaks"
In .NETTO-Perspektive:
- Was ist ein Speicherverlust?
- Wie können Sie bestimmen, ob Ihre Anwendung Lecks? Was sind die Auswirkungen?
- Wie kann man verhindern, dass ein memory leak?
- Wenn Ihre Anwendung hat Speicher-Lecks, geht es Weg, wenn der Prozess beendet wird oder getötet wird? Oder führen Sie Speicher-Lecks in Ihrer Anwendung auf andere Prozesse auf dem system, auch nach Abschluss eines Prozesses?
- Und was ist mit nicht verwalteten code, der Zugriff erfolgt über COM-Interop und/oder P/Invoke?
InformationsquelleAutor der Frage huseyint | 2008-08-01
Du musst angemeldet sein, um einen Kommentar abzugeben.
Die beste Erklärung, die ich gesehen habe, ist in Kapitel 7 des kostenlosen Grundlagen der Programmierung e-book.
Grundsätzlich in .NET ein Speicherverlust tritt auf, wenn ein Verweis auf die Objekte verwurzelt sind und daher nicht in die garbage Collection. Dies geschieht versehentlich, wenn Sie auf halten, um Referenzen über den vorgesehenen Anwendungsbereich.
Werden Sie wissen, dass Sie Lecks haben, wenn Sie anfangen, OutOfMemoryExceptions oder Ihre memory-Nutzung geht über das hinaus, was man erwarten würde (PerfMon hat schöne Erinnerung-Zähler).
Verständnis .NET's-Speicher-Modell, ist Ihre beste Weg zu vermeiden. Insbesondere das Verständnis, wie der garbage collector funktioniert und wie Referenzen funktionieren — wieder Verweise ich auf Kapitel 7 des e-book. Auch, darauf achten, häufige Fehlerquellen, die wohl am meissten Veranstaltungen. Wenn der Objekt - Eine der registriert ist, ein Ereignis auf das Objekt Bdann Objekt Eine bleiben, um, bis Objekt B verschwindet, weil B enthält einen Verweis auf Eine. Die Lösung ist, um die Registrierung Ihrer Veranstaltungen, wenn Sie fertig sind.
Natürlich, ein gutes Gedächtnis-Profil können Sie sehen, Ihre Objekt-Graphen und erkunden Sie die Schachteln/Referenzierung der Objekte, um zu sehen, wo Referenzen sind kommt und was root-Objekt zuständig ist (rote-Tor-Ameisen-ProfilJetBrains dotMemory, memprofiler sind wirklich eine gute Wahl, oder können Sie das nur-text - WinDbg und SOSaber würde ich dringend empfehlen, eine kommerzielle/visual Produkts, es sei denn, du bist ein echter guru).
Ich glaube nicht verwaltetem code unterliegt seine typische Speicherverluste, außer, dass der freigegebene Verweise verwaltet der garbage collector. Ich konnte falsch sein an diesem letzten Punkt.
InformationsquelleAutor der Antwort Karl Seguin
Streng genommen, kann ein Speicherverlust verbraucht Speicher, der nicht mehr "verwendet" durch das Programm.
"Nicht mehr verwendet" hat mehr als eine Bedeutung, es könnte bedeuten, "no more reference", das heißt, völlig nicht behebbar, oder es bedeuten könnte, verwiesen wird, wiederherstellbar, unbenutzt aber das Programm hält die Referenzen sowieso. Nur das spätere gilt .Net für perfekt verwaltete Objekte. Jedoch, nicht alle Klassen sind perfekt und irgendwann eine zugrunde liegende unmanaged konnte die Umsetzung der Ressourcen dauerhaft für diesen Prozess.
In allen Fällen, die Anwendung verbraucht mehr Speicher als unbedingt notwendig. Die Seiten-Effekte, abhängig von der Anzahl zugespielt, gehen konnte, ohne zur Verlangsamung verursacht durch übermäßige Sammlung, eine Reihe von memory-Ausnahmen und schließlich einen fatalen Fehler, gefolgt durch erzwungene Beendigung von Prozessen.
Wissen Sie, eine Anwendung hat ein problem mit dem Arbeitsspeicher, wenn die überwachung zeigt, dass mehr und mehr Speicher zugewiesen ist, um Ihren Prozess nach jeder garbage-collection-Zyklus. In einem solchen Fall, sind Sie entweder zu halten, zu viel im Speicher, oder einige zugrunde liegenden unmanaged Durchführung undicht ist.
Für die meisten Lecks sind die Ressourcen wiederhergestellt, wenn der Prozess beendet wird, jedoch einige Ressourcen sind nicht immer wiederhergestellt, einige konkrete Fälle, cursor GDI-handles sind berüchtigt für diese. Natürlich, wenn Sie haben eine Inter-Prozess-Kommunikations-Mechanismus, reservierten Speicher in den anderen Prozess würde nicht freigegeben werden, bis dieser Vorgang setzt oder beendet.
InformationsquelleAutor der Antwort Coincoin
Ich denke, die "was ist ein memory-leak" und "was sind die Auswirkungen" Fragen wurden beantwortet, gut schon, aber ich wollte noch ein paar mehr Dinge auf die anderen Fragen...
Wie zu verstehen, ob Ihre Anwendung Lecks
Ein interessanter Weg ist, zu öffnen perfmon und fügen Sie Spuren für # bytes in all heaps und # Gen 2 Sammlungen , in jedem Fall nur auf Ihren Prozess. Wenn die Ausübung einer bestimmten Funktion bewirkt, dass die Gesamtanzahl der bytes zu erhöhen, und dass der Speicher bleibt reserviert, nachdem die next-Gen-2-Sammlung, man könnte sagen, dass die Funktion Speicher verliert.
Wie um zu verhindern, dass
Andere gute Meinungen bekommen haben. Ich möchte nur hinzufügen, dass vielleicht die am häufigsten übersehen Ursache .NET memory leaks ist das hinzufügen von event-Handler-Objekte, ohne diese zu entfernen. Ein event-handler an das Objekt angefügt ist eine form der Referenz auf das Objekt, so wird verhindert, Sammlung, auch nachdem alle anderen Verweise gegangen. Immer daran denken, zu trennen event-Handler (mit der
-=
syntax in C#).Hat das Leck Weg, wenn der Prozess beendet wird, und was über COM-interop?
Wenn Ihr Prozess beendet ist, werden alle memory-mapped in seinem Adressraum ist, zurückgefordert von der OS, einschließlich aller COM-Objekte diente von DLLs. Vergleichsweise selten, COM-Objekte können serviert werden separate Prozesse. In diesem Fall, wenn ein Prozess beendet wird, können Sie immer noch die Verantwortung für den zugewiesenen Speicher in beliebige COM-server-Prozesse, die Sie verwendet.
InformationsquelleAutor der Antwort Martin
Ich würde definieren Speicherverluste als Objekt nicht der gesamte Speicher freigesetzt wird zugewiesen, nachdem es abgeschlossen wurde. Ich habe festgestellt, dass dies passieren kann in Ihrer Anwendung, wenn Sie mithilfe der Windows-API und COM (d.h. nicht verwaltetem code hat einen Fehler oder ist nicht korrekt verwaltet), die im Rahmen und in Komponenten von Drittanbietern. Ich habe auch nicht treiben nach der Verwendung von bestimmten Gegenständen, wie Stifte das Problem verursachen können.
Ich persönlich erlitten haben, Out-of-Memory-Ausnahmen, die verursacht werden können, sind aber nicht exklusiv für Speicherlecks in dot net-Anwendungen. OOM (können auch von pinning sehen Pinning Artikel). Wenn Sie sich nicht immer OOM Fehler oder bestätigen müssen, wenn es ein Speicherleck verursachen, dass es dann der einzige Weg ist, um ein Profil Ihrer Anwendung.
Ich würde auch versuchen, und stellen Sie Folgendes sicher:
a) Alles was Idisposable implementiert entsorgt wird entweder mit einem finally-block oder die using-Anweisung diese sind Pinsel, Stifte etc.(einige Leute streiten sich um alles, was zu nichts zusätzlich)
b)Alles, was ein close-Methode wieder geschlossen mit finally oder using-Anweisung (obwohl ich gefunden habe, nicht immer in der Nähe, je nachdem, ob Sie erklärten das Objekt außerhalb des using-Anweisung)
c)Wenn Sie nicht verwalteten code/windows-API ist, dass diese behandelt werden korrekt nach. (einige haben bereinigen Methoden zum freigeben von Ressourcen)
Hoffe, das hilft.
InformationsquelleAutor der Antwort John
Wenn Sie brauchen, um zu diagnostizieren ein Speicher-Leck .NET, prüfen Sie diesen links:
http://msdn.microsoft.com/en-us/magazine/cc163833.aspx
http://msdn.microsoft.com/en-us/magazine/cc164138.aspx
Diese Artikel beschreiben, wie erstellen Sie ein Speicherabbild des Prozesses und wie Sie zu analysieren, so dass Sie zunächst ermitteln, ob Ihre Leck unmanaged oder managed, und wenn Sie es geschafft, wie um herauszufinden, wo es herkommt.
Microsoft hat auch ein neueres Instrument zur Unterstützung der Generierung von crash dumps, zu ersetzen, ADPlus, genannt DebugDiag.
http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en
InformationsquelleAutor der Antwort Eric Z Beard
Mithilfe von CLR-Profiler von Microsoft http://www.microsoft.com/downloads/details.aspx?familyid=86ce6052-d7f4-4aeb-9b7a-94635beebdda&displaylang=en ist ein guter Weg, um zu bestimmen, welche Objekte halten, die im Gedächtnis ist, was die Ausführung flow führt zu der Schaffung dieser Objekte, und auch die überwachung, die Objekte Leben, wo auf dem heap (Fragmentierung, LOH, usw.).
InformationsquelleAutor der Antwort Nick
Ich denke, in einer verwalteten Umgebung befindet, ein Leck würde Sie halten eine unnötige Referenz auf ein großes Stück von dem Speicher um.
InformationsquelleAutor der Antwort Bernard
Die beste Erklärung, wie der garbage collector funktioniert, ist in Jeff Richters CLR via C# Buch, (Ch. 20). Lektüre dieses gibt ein gutes Fundament für das Verständnis, wie die Objekte bestehen.
Einer der häufigsten Ursachen der verwurzelung der Objekte versehentlich durch anschließen Veranstaltungen auch draußen eine Klasse. Wenn Sie hook up eine externe Veranstaltung
z.B.
und vergessen, zu trennen, wenn Sie nicht zu entsorgen, dann SomeExternalClass hat eine ref zu Ihrer Klasse.
Wie oben erwähnt, die SciTech Speicher-profiler ist ausgezeichnet, Sie zeigt die Wurzeln der Objekte, die Sie vermuten, sind undicht.
Aber es ist auch eine sehr schnelle Möglichkeit zu überprüfen, einen bestimmten Typ verwenden Sie einfach WnDBG (kann man sogar mit diesem in der VS.NET Direktfenster, während an):
Nun etwas tun, was Sie denken, wird über die Objekte dieses Typs (z.B. schließen eines Fensters). Es geht hier praktisch um eine debug-button irgendwo laufen wird
System.GC.Collect()
ein paar mal.Führen
!dumpheap -stat -type <TypeName>
wieder. Wenn die Zahl nicht nach unten gehen, oder gehen nicht so viel, wie Sie erwarten, dann haben Sie eine Grundlage für weitere Untersuchungen.(Ich habe diesen Tipp aus einem seminar gegeben durch Ingo Rammer).
InformationsquelleAutor der Antwort Gus Paul
Absolut. Auch, nicht mit dem .Dispose () - Methode auf Einweg-Objekte, wenn angemessen, kann die Ursache mem-leaks. Der einfachste Weg dies zu tun ist mit einem using-block verwenden, weil es automatisch ausgeführt wird .Dispose() am Ende:
Und wenn Sie eine Klasse erstellen, ist die Verwendung nicht verwalteter Objekte, wenn Sie nicht zu implementieren IDisposable korrekt, Sie könnte die Ursache von Speicherlecks, die für Ihre Klasse Benutzer.
InformationsquelleAutor der Antwort Seibar
Warum denken Menschen, dass ein Speicherleck im .NET ist nicht das gleiche wie jedes andere leak?
Ein Speicherleck ist, wenn Sie eine Verbindung zu einer Ressource und lassen Sie es nicht zu gehen. Sie können dies sowohl in verwalteten und nicht verwalteten Codierung.
Bezug .NET-und andere Programmier-tools, es wurden Ideen über das Müll sammeln und anderen Möglichkeiten der Minimierung von Situationen, mit denen Ihre Anwendung Leck.
Aber die beste Methode zu verhindern memory leaks ist, dass Sie brauchen, um zu verstehen, die zugrunde liegenden Speicher-Modell, und wie es funktioniert, auf der Plattform, die Sie verwenden.
Glauben, dass GC und andere magic clean up your mess, ist der kurze Weg, um Speicher Lecks, und wird schwierig sein, später zu finden.
Bei der Kodierung von nicht verwalteten Sie in der Regel stellen Sie sicher, zu bereinigen, Sie wissen, dass die Ressourcen, die Sie halten, wird Ihre Verantwortung sein, zu bereinigen, nicht der Hausmeister.
In .NET auf der anderen Seite, eine Menge Leute denken, dass die GC-reinigen alles aus. Nun, es tut etwas für Sie, aber Sie müssen sicherstellen, dass es so ist. .NET tut wickeln viele Dinge, so dass Sie nicht immer wissen, ob es sich um verwaltete oder nicht verwaltete Ressource, und Sie müssen sicherstellen, was Sie zu tun haben. Umgang mit Schriften, die GDI-Ressourcen, active directory, Datenbanken, etc ist in der Regel Dinge, die Sie brauchen, zu suchen.
Ich sehe viele Leute haben das aber, und ich hoffe wirklich, dass dies wird Ende. Sie können nicht bitten Sie den Benutzer zu kündigen, Ihre app zu bereinigen Ihre Durcheinander!
Werfen Sie einen Blick auf einen browser, der kann IE, FF etc, dann öffnen Sie, sagen wir, Google Reader, lassen Sie es bleiben für einige Tage, und schauen, was passiert.
Wenn Sie dann öffnen Sie eine andere Registerkarte im browser, surfen Sie auf eine Seite, schließen Sie dann die Registerkarte, die Gastgeber der anderen Seite, die den browser Leck, denken Sie, dass der browser den Speicher freizugeben? Nicht so mit dem IE. Auf meinem Rechner IE leicht zu Essen, 1 GB Speicher, in kürzester Zeit (etwa 3-4 Tage), wenn ich den Google Reader. Einige newspages sind noch schlimmer.
InformationsquelleAutor der Antwort neslekkiM
Alle Speicher-Lecks behoben werden, indem Beendigung des Programms.
Leck genug Speicher und das Betriebssystem kann entscheiden, um das problem zu beheben auf Ihrem Namen.
InformationsquelleAutor der Antwort Josh
Ich schließe mit Bernard zu .net, was ein mem-leak wäre.
Könnten Sie ein Profil Ihrer Anwendung, um zu sehen, seine Speicher zu verwenden, und bestimmen, dass, wenn seine Verwaltung eine Menge Speicher, wenn es nicht sein sollte, man könnte sagen, es hat ein Leck.
In verwaltete Ausdrücke ich lege meinen Hals auf der Linie zu sagen, es wird Weggehen, sobald der Prozess wird gekillt/gelöscht.
Nicht verwalteten code ist seine eigene Bestie und wenn ein Leck vorhanden ist, wird es Folgen ein standard mem. Leck definition.
InformationsquelleAutor der Antwort Pat
Beachten Sie auch, dass .NET hat zwei Haufen, einer, der large object heap. Ich glaube, dass Objekte von rund 85k oder größer gesetzt sind, auf diesen Haufen. Dieser Haufen hat eine andere Lebensdauer-Regeln als die regelmäßige heap.
Wenn Sie große Speicher-Strukturen (Wörterbuch oder eine Liste ist), wäre es klug, zu gehen, lookup, was die genauen Regeln sind.
Soweit die Rückforderung der Speicher auf Beendigung des Prozesses, es sei denn, Ihr unter Win98 oder äquivalente, alles wird wieder abgegeben, um das OS auf die Kündigung. Die einzigen Ausnahmen sind Dinge, die geöffnet werden, cross-Prozess, und ein anderer Prozess noch hat die Ressource öffnen.
COM-Objekte kann schwierig sein, tho. Wenn man immer die
IDispose
Muster, werden Sie sicher sein. Aber ich habe über ein paar interop-Assemblys, die UmsetzungIDispose
. Der Schlüssel ist hier zu nennenMarshal.ReleaseCOMObject
wenn Sie fertig sind mit ihm. Die COM-Objekte verwenden immer noch standard-COM-Referenzzählung.InformationsquelleAutor der Antwort Joel Lucsy
Fand ich .Net Memory Profiler eine sehr gute Hilfe bei der Suche nach Speicherlecks in .Net. Es ist nicht kostenlos, wie auch die Microsoft CLR Profiler, aber schneller und mehr auf den Punkt, meiner Meinung nach. Ein
InformationsquelleAutor der Antwort Lars Truijens
Einer definition ist: Nicht zu release nicht erreichbar, Speicher, kann nicht mehr zugewiesen werden, um neue Prozess während der Ausführung der Zuweisung von Prozess. Es können meist geheilt werden, indem mittels GC-Techniken oder erkannt werden durch automatisierte tools.
Weitere Informationen, besuchen Sie bitte http://all-about-java-and-weblogic-server.blogspot.in/2014/01/what-is-memory-leak-in-java.html.
InformationsquelleAutor der Antwort hemant kurmi