Frage

Ich habe eine Windows App, die Speicher zu verlieren scheint, so habe ich Redgate ANTS Memory Profiler an den Objekten zu suchen Ich vermute, und feststellen, dass sie nur durch Objekte, die bereits auf der Seite Finalizer Queue gehalten werden. Große, genau das, was ist eine der Finalizer Queue? Können Sie mir zeigen auf die beste Definition? Können Sie ein anekdotischen Ratschläge teilen?

Auch alle Wurzel GC Objekte auf der Finalizer Queue sind Instanzen von System.Windows.Forms.Control + ThreadMethodEntry Objekte namens "Anrufer". Ich sehe, dass es in Multi-Thread-UI-Interaktion beteiligt ist, aber ich weiß nicht viel darüber hinaus. Verzeihen Sie meine scheinbare Trägheit und gab zu Unwissenheit, aber diese Ressourcen sind alle innerhalb eines Anbieters Komponente begraben. Ich spreche mit dem Verkäufer über diese Fragen, aber ich brauche etwas Richtung mich aufstehen, das Gespräch zu beschleunigen auf. Können Sie mir zeigen auch auf die nützlichsten Definition von ThreadMethodEntry? Alle anekdotische Rat?

Auch soll ich auch über diese Objekte auf der Finalizerthread Warteschlange betroffen sein?

Update: Das Red Gate Artikel hilfreich war.

War es hilfreich?

Lösung

Die Finalizerthread Warteschlange enthält alle Objekte, die eine Finalizer-Methode definiert haben. Es sei daran erinnert, dass ein Finalizerthread ein Mittel ist nicht verwalteten Ressourcen wie Griffe zu sammeln. Wenn der Speicherbereinigungs garbage sammelt, bewegt er alle Objekte, mit einem in die finalizer finalizer Warteschlange. Irgendwann later-- je nach Speicherdruck, GC Heuristiken und die Phase des moon--, wenn der Garbage Collector diese Objekte zu sammeln entscheidet, geht es um die Warteschlange nach unten und führt die Finalizers.

Nachdem mit Speicherlecks in der Vergangenheit zusammengearbeitet, ein Bündel Ihrer Lieferanten Objekte in der Warteschlange Finalizerthread sehen könnte schlampig Code sein, aber es gibt nicht ein Speicherleck. Typischerweise wird ein guter Code eine Dispose-Methode machen, die beide verwalteten und nicht verwalteten Ressourcen sammeln, und so, entfernt sich von der Finalizerthread Warteschlange über GC.SuppressFinalize() dabei. Also, wenn die Objekte des Anbieters eine Dispose-Methode implementieren, und Ihr Code ist es nicht nennen, das zu einer Reihe von Objekten in der Finalizer-Warteschlange führen könnte.

Haben Sie versucht, einen Schnappschuss in ANTS zwischen zwei Zeitpunkten erstellen und die Objekte zwischen ihnen geschaffen zu vergleichen? Das kann Ihnen dabei helfen, alle verwalteten Objekte durchgesickert.

Auch wenn Sie weg, wenn der Speicher sehen wollen, geht, wenn die Finalizer ausgeführt werden, versuchen Sie dies nur zu testen, mit:

System.GC.Collect();
System.GC.WaitForPendingFinalizers(); // this method may block while it runs the finalizers
System.GC.Collect();

Ich empfehle nicht, diesen Code normal läuft. Vielleicht möchten Sie es laufen, wenn Sie nur eine Menge Arbeit und erstellt eine Menge Müll getan haben. Zum Beispiel in unserer App, eine unserer Funktionen können über 350 MB Müll schaffen, das nach dem Schließen eines MDI-Fenster geht zu vergeuden. Da dies bekannt ist, eine Menge Müll zu verlassen, zwingen wir manuell Garbage Collection.

Beachten Sie auch, dass es eine Low-Level-Cache-Eigenschaft in der Basis Windows.Forms-Code, der auf den letzten modalen Dialog geöffnet hält, wird. Dies könnte eine Quelle für ein Speicherleck sein. Ein sicherer Weg, diese Referenz loszuwerden ist, ein anderen einfachen Dialog zu zwingen, zu erscheinen, dann führen Sie den oben GC-Code.

Andere Tipps

Die Finalizer-Warteschlange ist eine Warteschlange, wo die Objektinstanzen, die nicht mehr verwendet werden, warten darauf, von der GC abgeschlossen sein. Alle Objekte in dieser Warteschlange werden fertig gestellt und Ihre Speicherlecks sind wahrscheinlich von einem diesen diejenigen direkt nicht kommen. Aber eines dieser Objekte können nicht alle seine nicht verwalteten Ressourcen freigeben.

Die ThreadMethodEntry-Klasse ist eine Implementierung von IAsyncResult und Instanzen dieser Klasse normalerweise erstellt, wenn asynchrone Operationen aufrufen, wie Invoke über die Benutzeroberfläche zu aktualisieren oder zu verwenden beginnen * / Ende * Methoden.

Hier ist eine gute Blog-Post, die ein ähnliches Problem beschreibt. Auf einer technischen Ebene könnten Sie mit SOS.dll aussehen (das ist der Blog-Eintrag beschreibt) und

scroll top