Wie kann ich Speicher freigeben, der von einer Parallel.Task verwendet wird?

8

Ich habe ein Programm, das eine speicherintensive Simulation ausführt. Im Folgenden habe ich eine kleine Konsolenanwendung geschrieben, die das Problem reproduziert, das ich habe.

%Vor%

Wenn ich das Programm starte, sehe ich, wie viel Speicher im Windows-Task-Manager verbraucht wird, aber wenn die Task beendet ist (und "Done" angezeigt wird), geht der Speicher nicht auf den ursprünglichen Level zurück. das passiert nur, wenn ich die Anwendung schließe.

Weiß jemand, wie man Speicher freisetzt, der von einer parallelen Aufgabe benutzt wird, während die Hauptanwendung läuft? Wie Sie sehen können, habe ich bereits versucht, es zu entsorgen, seinen Bezug auf null zu setzen und den Garbage Collector manuell auszuführen (was Sie nicht tun sollten, ich weiß).

    
jkokorian 28.11.2011, 08:38
quelle

2 Antworten

4

Ich bin sicher, dass Sie kein Problem mit Ihrem Speicher haben, .NET schrumpft den verwendeten Speicher nicht so, dass er in Zukunft zugeordnet werden kann. Dies spart Zeit für zukünftige Speicherzuweisung. Versuchen Sie, die Schleife nach dem Beenden erneut auszuführen, ich bin mir sicher, dass der Speicher nicht wachsen wird.

Also bitte versuchen Sie das, ich wäre am Ergebnis interessiert!

%Vor%

Diese beiden Methoden werden verwendet, um die Speichernutzung auszudrucken:

%Vor%

Meine Ausgabe ist:

%Vor%

Soweit ich sehen kann, gibt es hier kein Speicherproblem. Die Objekte sind sauber und der Speicher wird wiederverwendet. Problem gelöst oder?

Aktualisieren

Verhalten der privaten Bytes:

Wie Sie sehen können, sammelt der GC die Objekte und gibt den Speicher frei, aber er gibt ihn momentan nicht frei, so dass neue Objekte zugewiesen werden können.

    
oberfreak 28.11.2011, 09:39
quelle
6

Dies liegt an der Natur eines concurrentBag (siehe meine frühere Frage zu ConcurrentBag ( Mögliche Speicherlecks in ConcurrentBag) ? )).

Grundsätzlich speichert eine gleichzeitige Tasche Elemente im lokalen Thread. Wenn Sie die Artikel nicht konsumieren, bleiben die Artikel im lokalen Thread erhalten. Bitte überprüfen Sie das folgende Beispiel:

%Vor%

Der concurrentBag verwendet die ThreadLocal-Klasse, die es praktisch macht, 1 Instanz pro Thread zu halten. Die beabsichtigte Möglichkeit, Daten in einem ThreadLocal zu verteilen, besteht darin, die Dispose-Methode auf ThreadLocal (ThreadLocal implementiert IDisposable) aufzurufen. Dadurch werden nur die Daten für den aktuellen Thread verfügbar. Der ConcurrentBag verfügt jedoch nicht über seine ThreadLocals. Stattdessen hängt es davon ab, dass alle Elemente konsumiert werden - oder ein Thread, der das ThreadLocal enthält, das entsorgt wird. Dies kann jedoch sehr unangenehm sein, wenn Sie Threads wie in einem ThreadPool teilen.

    
Polity 28.11.2011 08:50
quelle

Tags und Links