Frage

In meiner Anwendung habe ich viele RichText -Kästchen, die in der Laufzeit dynamisch erstellt werden. Ich habe festgestellt, dass die Anwendung über ein Speicherleck verfügt, das durch die Richtextbox -Steuerelemente verursacht wird. Um zu beweisen, dass der Speicher aufgrund der Steuerung die folgende Testmethode geschrieben habe:

for (int i = 0; i < 3000; i++)
        {
            Control rich = new RichTextBox();
            pnl.Content = rich;
        }
GC.Collect();
GC.WaitForPendingFinalizers();

pnl ist ein ContentControl, das in XAML -Code deklariert wird.
Wenn Sie den folgenden Code ausführen, können Sie feststellen, dass die Speicherverwendung schnell wächst.

Irgendwelche Ideen, wie man das Problem löst? Ich überlegte, einen Objektpool zu erstellen, aber dies würde meine Anwendung erschweren, und ich vermeide ihn lieber.


bearbeiten: Ich habe den Müllkollektor Anruf hinzugefügt, um zu demonstrieren, dass die Objekte nicht Müll gesammelt sind - es gibt keine Verbesserung der Speicherverwendung mit und ohne den Aufruf der GC -Sammelmethode. Beachten Sie diese Anrufe rich.Dispose Innerhalb der Schleife eliminiert das Wachstum des Gedächtnisverbrauchs.

War es hilfreich?

Lösung

Ich habe dies an anderer Stelle gefunden, und es scheint korrekt zu sein, was meine Tests betrifft.

Wenn ein FlowDocument erstellt wird, werden auch relativ teure Formatierungskontextobjekte für ihn in seinem Strukturcache erstellt. Wenn Sie mehrere Flowdocs in einer engen Schleife erstellen, wird für jeden FlowDOC ein Strukturcache erstellt. Lassen Sie sich am Ende der Schleife GC.Collect anrufen, in der Hoffnung, etwas Speicher wiederherzustellen. StructuralCache hat einen Finalizer veröffentlicht diesen formatierenden Kontext, jedoch nicht sofort. Der Finalizer plant effektiv eine Operation, um Kontexte in DispatcherPriority zu veröffentlichen. Background.

Die Richtextbox (oder FlowDocument), falls nicht nur auf einen Hintergrund -Thread aufgeräumt wird. Wenn es genau läuft, wer weiß. Ich wünschte, dies habe gerade eine Entsendung Methode implementiert, die eine Reinigung sofort erzwingen würde.

Andere Tipps

Dies ist kein Hinweis darauf, dass Ihre Anwendung über ein Speicherleck verfügt. Dies ist ein Hinweis darauf, dass Ihre Anwendung ist viel Speicher verwenden. Es ist ein Leck, wenn die RichTextBox Die Bedienelemente werden irgendwann nicht freigegeben, nachdem sie aus dem Spielraum gefallen sind (das Erkennen von Speicherlecks auf verwalteten Objekten ist notorisch schwierig und unbegeibt).

Ein weit verbreitetes Missverständnis, dass ein aus dem Zielfernrohr fälliger Objekt einen Müll gesammelt hat. Das macht es nur berechtigt gesammelt werden. Das Objekt kann theoretisch noch nie gesammelt werden, bis die Anwendung endet. Die Tatsache, dass es mit wächst mit RichTextBox und nicht mit anderen Kontrollen ist kein Hinweis darauf, dass ein Speicherleck in der vorhanden ist RichTextBox, Es ist nur ein Hinweis darauf, dass es mehr Speicher pro Instanz verwendet als andere Steuerelemente. Diese Informationen können zwar nützlich sein, hilft zwar nicht hilfreich, wenn festgestellt wird, ob ein Speicherleck vorliegt oder nicht.

Wir hatten das gleiche Problem in Winforms 2.0 und mussten eine dritte Textkontrolle kaufen. Ich denke, Microsoft hat sich nicht die Mühe gemacht, es zu beheben ...

Dies hat mir das Problem behoben:http://blingcode.blogspot.com/2010/10/memory-leak-with-wpfs-richttextbox.html

Fügen Sie im Grunde zwei Attribute zu jeder Richtextbox hinzu :) :) isundoenabled = "False"

In Bezug auf Ihre Bearbeitung:

Sie haben die GC -Anrufe hinzugefügt nach Der Schleifen endet und alle 3000 RichTextBoxEs wurden geschaffen.

Ich bin damit einverstanden, dass es seltsam erscheint, dass der vorherige nicht in der Schleife befreit wird, wenn er durch einen neuen ersetzt wird, ist es so ein so enger Schleifen endet.

Ich denke nicht, dass es eine gute Idee ist (aber im Testcode sollte es in Ordnung sein), aber haben Sie versucht, die GC -Anrufe in der Schleife zu verschieben?

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top