Anatomie eines „Memory Leak“

stimmen
159

In .NET Perspektive:

  • Was ist ein Speicherleck ?
  • Wie können Sie, ob Ihre Anwendung Lecks bestimmen? Was sind die Auswirkungen?
  • Wie können Sie einen Speicherverlust verhindern?
  • Wenn Ihre Anwendung Speicherleck hat, ist es weg, wenn der Prozess verlässt oder getötet wird? Oder beeinflussen Speicherlecks in Ihrer Anwendung andere Prozesse auf dem System auch nach Abschluss des Prozesses?
  • Und was nicht verwalteten Code über COM Interop zugegriffen und / oder P / Invoke?
Veröffentlicht am 01/08/2008 um 16:12
quelle vom benutzer
In anderen Sprachen...                            


15 antworten

stimmen
106

Die beste Erklärung , die ich gesehen habe , ist in Kapitel 7 der freien Grundlagen der Programmierung E-Book .

Im Grunde genommen in .NET ein Speicherverlust tritt auf, wenn referenzierte Objekte verwurzelt sind und somit nicht Müll gesammelt werden kann. Dies geschieht zufällig , wenn Sie den beabsichtigten Umfang halten, um Referenzen darüber hinaus.

Sie wissen , dass Sie Lecks haben , wenn Sie immer OutOfMemoryExceptions oder Speicherauslastung steigt über beginnen , was man erwarten würde ( PerfMon schön Speicherzähler hat).

Das Verständnis .NET ‚s - Speicher - Modell ist der beste Weg , es zu vermeiden. Genauer gesagt, zu verstehen , wie der Garbage Collector funktioniert und wie Referenzen zu arbeiten - auch hier verweise ich Sie auf Kapitel 7 des E-Book. Seien Sie auch, gemeinsamer Gefahren bewusst, die wohl gängigste Anlässe. Wenn das Objekt A zu einer Veranstaltung am Objekt registriert ist B , dann das Objekt A wird bleiben , um bis zum Objekt B verschwindet , weil B einen Verweis auf hält A . Die Lösung ist Ihre Veranstaltungen deregistrieren , wenn Sie fertig sind.

Natürlich wird ein gutes Gedächtnis - Profil können Sie Ihre Objektgraphen sehen und die Verschachtelung / Referenzierung Ihrer Objekte erforschen , um zu sehen , wo Referenzen und Objekt ist verantwortlich , was Wurzel kommen ( rot-Gate - Ameisen - Profil , JetBrains dotMemory, memprofiler sind wirklich gut Entscheidungen, oder können Sie das Text-only verwenden WinDbg und SOS , aber ich würde stark kommerzielle / visuelles Produkt empfehlen , wenn Sie ein echter Guru sind).

Ich glaube, nicht verwalteten Code zu seinen typischen Speicherlecks ausgesetzt ist, mit der Ausnahme, dass die gemeinsamen Referenzen vom Garbage Collector verwaltet werden. Ich könnte über diesen letzten Punkt falsch.

Beantwortet am 01/08/2008 um 16:28
quelle vom benutzer

stimmen
32

Streng genommen ist ein Speicherverlust verbraucht Speicher, der „nicht mehr verwendet“ durch das Programm.

„Nicht mehr verwendet“ mehr als eine Bedeutung hat, könnte es „nicht mehr Bezug auf sie“ bedeuten, das heißt, völlig nicht behebbar, oder es könnte bedeuten, verwiesen, wiederherstellbare, ungebrauchte aber das Programm hält ohnehin die Referenzen. Nur die später gilt für .NET perfekt verwalteten Objekte . Allerdings sind nicht alle Klassen sind perfekt und irgendwann eine darunter liegende nicht verwaltete Implementierung könnte Ressourcen dauerhaft für diesen Prozess auslaufen.

In allen Fällen verbraucht die Anwendung mehr Speicher als unbedingt erforderlich. Die Seiten Effekte, abhängig von der ammount durchgesickert, konnten von keinem gehen, zu Verlangsamung durch übermäßige Ansammlung verursacht, zu einer Reihe von Speichern Ausnahmen und schließlich ein tödlichen durch Zwangsprozessbeendigung gefolgt Fehler.

Sie wissen , dass eine Anwendung ein Speicherproblem hat , wenn die Überwachung zeigt , dass mehr und mehr Speicher für Ihren Prozess zugeordnet wird nach jedem Garbage - Collection - Zyklus . In einem solchen Fall halten Sie entweder zu viel im Speicher oder einige zugrunde liegenden unmanaged Implementierung ist undicht.

Für die meisten Lecks, Ressourcen zurückgewonnen werden, wenn der Prozess beendet ist, jedoch einige Ressourcen nicht immer in einigen Fällen präzise erholt, sind GDI Cursor Griffe für die berüchtigt. Natürlich, wenn Sie einen Interprozess-Kommunikationsmechanismus haben, würden in dem anderen Prozess zugewiesenen Speicher nicht freigegeben werden, bis dieser Prozess beendet ihn oder befreit.

Beantwortet am 01/08/2008 um 18:52
quelle vom benutzer

stimmen
28

Ich denke, die „was für ein Speicherleck ist“ und „was die Auswirkungen sind“ Fragen auch bereits beantwortet, aber ich wollte noch ein paar Dinge, auf den anderen Fragen hinzufügen ...

Wie, ob Ihre Anwendung Lecks verstehen

Eine interessante Art und Weise zu öffnen perfmon und fügen Sie Spuren für # Bytes in allen Haufen und # Gen 2 Sammlungen , jeweils einfach nur an Ihrem Prozess. Wenn die Ausübung erhöhen , um eine bestimmte Funktion bewirkt , dass die Gesamtzahl der Bytes, und dass der Speicher bleibt nach der nächsten Gen 2 Sammlung zugeordnet, könnte man sagen , dass die Funktion Speicherlecks.

Wie man etwas vorbeugt

Andere gute Meinungen gegeben worden. Ich würde nur hinzufügen , dass vielleicht die am häufigsten übersehen Ursache von .NET Speicherlecks ohne Entfernen von ihnen Event - Handler - Objekte hinzuzufügen ist. Ein Event - Handler an einem Objekt angebracht ist eine Form der Verweis auf dieses Objekt wird so verhindert Sammlung selbst , nachdem alle anderen Referenzen gegangen sind. Denken Sie immer daran Event - Handler (mit der abzulösen -=Syntax in C #).

Ist das Leck weg, wenn der Prozess beendet wird, und dem, was über COM-Interop?

Wenn Ihr Prozess beendet wird, werden alle Speicher in seinen Adressraum abgebildet wird durch das OS freigegeben, darunter alle COM-Objekte aus DLLs serviert. Vergleichsweise selten, können COM-Objekte aus separaten Prozessen bedient werden. In diesem Fall, wenn der Prozess beendet wird, können Sie immer noch für Speicher in allen COM-Server-Prozessen zugewiesen verantwortlich, die Sie verwendet haben.

Beantwortet am 15/08/2008 um 17:11
quelle vom benutzer

stimmen
18

Wenn Sie ein Speicherleck in .NET diagnostizieren müssen, überprüfen Sie diese Links:

http://msdn.microsoft.com/en-us/magazine/cc163833.aspx

http://msdn.microsoft.com/en-us/magazine/cc164138.aspx

Diese Artikel beschreiben, wie ein Speicherabbild des Prozesses zu erstellen und wie es zu analysieren, so dass Sie zunächst feststellen, ob Ihr Leck nicht verwaltet oder verwaltet werden, und wenn es verwaltet wird, wie um herauszufinden, wo es herkommt.

Microsoft hat auch ein neueres Werkzeug mit der Erzeugung von Crash-Dumps zu unterstützen, ersetzen ADPlus, genannt DebugDiag.

http://www.microsoft.com/downloads/details.aspx?FamilyID=28bd5941-c458-46f1-b24d-f60151d875a3&displaylang=en

Beantwortet am 15/08/2008 um 00:16
quelle vom benutzer

stimmen
18

Ich würde Speicherlecks als ein Objekt nicht die Freisetzung gesamte Speicher definieren zugewiesen, nachdem es abgeschlossen ist. Ich habe gefunden, dies in Ihrer Anwendung passieren kann, wenn Sie Windows-API und COM verwenden (dh nicht verwalteten Code, der einen Fehler in er hat oder nicht richtig verwaltet wird), im Rahmen und in Komponenten von Drittanbietern. Ich habe festgestellt tiding auch nicht nach der Verwendung von bestimmten Objekten wie Stifte können das Problem verursachen.

Ich persönlich habe nicht genügend Arbeitsspeicher Ausnahmen gelitten , die verursacht werden können , aber nicht exklusiv für Speicherlecks in dot net - Anwendungen. (OOM kann auch kommen sehen Pinning Pinning Artical ). Wenn Sie nicht OOM Fehler bekommen oder müssen , um zu bestätigen , ob es sich um ein Speicherleck verursacht es dann der einzige Weg , um Ihre Anwendung zu profilieren ist.

Ich würde auch versuchen und sicherzustellen, dass die folgenden:

a) Alles, was IDisposable implementiert entweder entsorgt wird mit einem finally-Block oder die Anweisung using dazu gehören Pinsel, Stifte usw. (einige Leute behaupten, alles zu nichts zusätzlich zu setzen)

b) Alles, was eine enge Methode hat wieder geschlossen mit endlich oder der Anweisung using (obwohl ich gefunden habe, mit nicht immer in der Nähe je nachdem, ob Sie das Objekt außerhalb der using-Anweisung deklarieren)

c) Wenn Sie mit nicht verwalteten Code / Windows-API ist, dass diese mit korrekt nach behandelt werden. (Einige haben Methoden aufzuräumen Ressourcen freizugeben)

Hoffe das hilft.

Beantwortet am 01/08/2008 um 18:57
quelle vom benutzer

stimmen
15

Mit 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 Haltespeicher, welcher Ausführungsablauf führen zur Schaffung dieser Objekte und die Überwachung auch die in dem auf dem Heap (Fragmentierung, LOH, etc.) Live - Objekte.

Beantwortet am 16/08/2008 um 20:54
quelle vom benutzer

stimmen
14

Die beste Erklärung dafür , wie der Garbage Collector arbeitet , ist in Jeff Richters CLR via C # Buch (Kap. 20). Lesen dies gibt eine große Erdung für das Verständnis , wie Objekte bestehen.

Eine der häufigsten Ursachen für Objekte aus Versehen Verwurzelung ist durch die Ereignisse outisde einer Klasse Einhaken. Wenn Sie ein externes Ereignis anschließen

z.B

SomeExternalClass.Changed += new EventHandler(HandleIt);

und vergessen, es zu auszuhängen, wenn Sie entsorgen, dann SomeExternalClass einen ref Ihrer Klasse hat.

Wie oben erwähnt, ist der SciTech Speicher - Profiler ist ausgezeichnet Sie Wurzeln von Objekten zu zeigen , Sie sind undicht vermuten.

Aber es ist auch eine sehr schnelle Möglichkeit, eine bestimmte Art zu überprüfen, ist die Verwendung nur WnDBG (Sie können sogar verwenden, in den VS.NET sofortigen Fenstern, während im Anhang):

.loadby sos mscorwks
!dumpheap -stat -type <TypeName>

Jetzt tun etwas , das Sie denken , werden die Objekte dieses Typs (zB in der Nähe eines Fensters) entsorgen. Hier ist es praktisch , eine Debug - Taste irgendwo haben, läuft System.GC.Collect()ein paar Mal.

Dann laufen !dumpheap -stat -type <TypeName>wieder. Wenn die Zahl nicht nach unten gehen, oder nicht so viel nach unten gehen , wie Sie erwarten, dann haben Sie eine Grundlage für weitere Untersuchungen. (Ich habe diesen Tipp von einem Seminar gegeben Ingo Rammer ).

Beantwortet am 27/08/2008 um 15:12
quelle vom benutzer

stimmen
14

Ich denke, in einer verwalteten Umgebung, ein Leck wäre Sie einen unnötigen Verweis auf einen großen Teil des Speichers zu halten um.

Beantwortet am 01/08/2008 um 16:19
quelle vom benutzer

stimmen
10

Warum glauben Menschen, dass ein Speicherleck in .NET ist nicht das gleiche wie jeder andere Leck?

Ein Speicherverlust ist, wenn Sie auf eine Ressource befestigen und lassen Sie es nicht gehen. Sie können dies sowohl für verwaltete und nicht verwaltete in Codierung.

.NET In Bezug und andere Programmiertool, gibt es Ideen gewesen über Müll sammeln, und andere Möglichkeiten, Situationen zu minimieren, die Ihre Anwendung Leck machen. Aber die beste Methode, Speicherlecks zu verhindern, ist, dass Sie benötigen, um Ihr zugrunde liegendes Speichermodell zu verstehen, und wie die Dinge arbeiten, auf der Plattform, die Sie verwenden.

Im Glauben, dass GC und andere Magie Ihre Schlamassel aufzuräumen ist der kurze Weg zu Speicherlecks und wird schwierig sein, später zu finden.

Wenn nicht verwalteten Codierung, stellen Sie in der Regel sicher zu reinigen, wissen Sie, dass die Ressourcen nehmen Sie halten, wird Ihre Verantwortung, um aufzuräumen, nicht die Hausmeister sein.

In .NET auf der anderen Seite, denken viele Leute, dass die GC alles aufräumt. Nun, es hat einige für Sie, aber Sie müssen sicherstellen, dass es so ist. .NET umbrochen viele Dinge, so dass Sie wissen nicht immer, wenn Sie mit einem verwalteten oder nicht verwalteten Ressource zu tun haben, und Sie müssen sicherstellen, was, was Sie zu tun haben. Umgang mit Schriftart, GDI-Ressourcen, Active Directory, Datenbanken usw. sind in der Regel Dinge, die Sie brauchen, wo sie nach.

In verwalteten Begriffen werde ich meinen Hals aufs Spiel setzen, zu sagen, dass es weg geht, wenn der Prozess abgebrochen wird / entfernt.

Ich sehe viele Leute, obwohl diese haben, und ich hoffe wirklich, diese enden wird. Sie können den Benutzer auffordern, Ihre App, um aufzuräumen Ihre Verwirrung zu beenden! Werfen Sie einen Blick auf ein Browser, das kann sein, IE, FF usw., dann öffnen, sagen wir, Google Reader, lassen Sie es für ein paar Tage bleiben, und schauen, was passiert.

Wenn Sie dann ein anderes Register im Browser öffnen, surfen zu einem gewissen Ort, dann die Registerkarte schließen, die die andere Seite gehostet, die den Browser Leck gemacht, denken Sie, der Browser den Speicher freigeben wird? Nicht so mit dem IE. Auf meinem Computer wird IE essen leicht 1 GiB Arbeitsspeicher in kürzester Zeit (ca. 3-4 Tage), wenn ich Google Reader verwenden. Einige Newsseiten sind noch schlimmer.

Beantwortet am 01/09/2008 um 13:19
quelle vom benutzer

stimmen
10

Ich denke, in einer verwalteten Umgebung, ein Leck wäre Sie einen unnötigen Verweis auf einen großen Teil des Speichers zu halten um.

Absolut. Auch nicht die .Dispose () -Methode auf Einweg-Objekte zu verwenden, wenn entsprechende kann mem Lecks verursachen. Der einfachste Weg, es zu tun ist, mit einem Block, weil es unter Verwendung .Dispose () am Ende automatisch ausführt:

StreamReader sr;
using(sr = new StreamReader("somefile.txt"))
{
    //do some stuff
}

Und wenn Sie eine Klasse erstellen, die nicht verwalteten Objekte verwendet, wenn Sie nicht IDisposable korrekt Implementierung, könnten Sie Speicherlecks verursacht sein für die Nutzer Ihre Klasse.

Beantwortet am 05/08/2008 um 23:47
quelle vom benutzer

stimmen
9

Alle Speicherlecks sind durch Programmende aufgelöst.

Leck genügend Speicher und das Betriebssystem entscheidet, kann das Problem in Ihrem Namen zu lösen.

Beantwortet am 04/08/2008 um 15:09
quelle vom benutzer

stimmen
9

Ich werde wie in .net mit Bernard übereinstimmen, was ein mem Leck wäre.

Sie könnten Ihr Anwendungsprofil seinem Speicher Verwendung zu finden und feststellen, dass, wenn seine viel Speicher verwalten, wenn es nicht sein sollte, man könnte sagen, es hat ein Leck.

In verwalteten Begriffen werde ich meinen Hals aufs Spiel setzen, zu sagen, dass es weg geht, wenn der Prozess abgebrochen wird / entfernt.

Unmanaged Code ist sein eigenes Tier und wenn ein Leck in ihm vorhanden ist, wird es ein Standard-Speicher folgen. Leck-Definition.

Beantwortet am 01/08/2008 um 16:23
quelle vom benutzer

stimmen
7

Auch bedenken Sie, dass .NET zwei Haufen hat, ist einer der großen Objektheap zu sein. Ich glaube, dass Objekte von rund 85k oder größer sind auf dieser Halde gelegt. Dieser Haufen hat eine andere Lebensdauer Regeln als die regulären Haufen.

Wenn Sie große Speicherstrukturen (Dictionary oder List) erstellen, wäre es klug zu gehen nachschlagen, was die genauen Regeln sind.

Soweit die Erinnerung an Prozessbeendigung Rückgewinnung, es sei denn, Ihr Win98 läuft oder es Äquivalente ist alles auf das OS auf Beendigung freigegeben zurück. Die einzigen Ausnahmen sind Dinge, die prozessübergreifende und ein anderer Prozess noch geöffnet sind, hat die Ressource geöffnet.

COM - Objekte können tückisch tho sein. Wenn Sie immer das verwenden IDisposeMuster, werden Sie sicher sein. Aber ich habe über ein paar Interopassemblys ausführen , die implementieren IDispose. Der Schlüssel ist hier zu nennen , Marshal.ReleaseCOMObjectwenn Sie mit ihm fertig sind. Die COM - Objekte noch Standard - COM - Referenzzählung verwenden.

Beantwortet am 07/08/2008 um 14:17
quelle vom benutzer

stimmen
6

Ich fand .NET Memory Profiler eine sehr gute Hilfe , wenn Speicherlecks in .Net zu finden. Es ist nicht kostenlos , wie der Microsoft CLR Profiler, ist aber schneller und mehr auf den Punkt meiner Meinung nach . EIN

Beantwortet am 20/08/2008 um 19:39
quelle vom benutzer

stimmen
1

Eine Definition ist: Kann nicht unerreichbaren Speicher freizugeben, der nicht mehr zu neuen Prozess zugeordnet werden können , während der Ausführung des Prozesses zuzuweisen. Es kann vor allem durch Verwendung von GC - Techniken oder detektiert durch automatisierte Werkzeuge gehärtet werden.

Für weitere Informationen, besuchen Sie bitte http://all-about-java-and-weblogic-server.blogspot.in/2014/01/what-is-memory-leak-in-java.html .

Beantwortet am 27/08/2014 um 16:22
quelle vom benutzer

Cookies help us deliver our services. By using our services, you agree to our use of cookies. Learn more