Warum reserviert mein Winforms-Programm so viel virtuellen Speicher?

8

Ich habe eine C # /. NET 4.0-Anwendung, die beim Start zwei Fenster mit etwa einem Dutzend Steuerelementen zeigt. Wenn ich mein Programm starte (Debug oder Release spielt keine Rolle), sehe ich im Task Manager / Resource Monitor, dass mein Programm bereits über 450 MB privaten Speicher hat. Ich weiß, dass der Task-Manager nicht die zuverlässigste Methode ist, die Speichernutzung zu messen, aber er ist für meine Benutzer am sichtbarsten.

Wenn ich die VS2010 .NET Memory Allocation-Leistungsanalyse für eine vollständige Ausführung meines Programms durchführe, meldet sie etwa 5 MB RAM, die tatsächlich für verwaltete Objekte zugewiesen sind (mein Programm verwendet normalerweise auch ein paar nicht verwaltete Objekte, aber sie sind sehr klein und um diese Untersuchung zu vereinfachen habe ich sie deaktiviert, allerdings ohne nennenswerten Effekt. Ebenso, wenn ich EmptyWorkingSet () von psapi.dll aufrufe, nachdem mein Hauptformular angezeigt wurde, sinkt mein privater Speicher auf ~ 3,5 MB.

Ich habe mir bereits die Fragen zu Speicherabdrücken hier angesehen hier , aber diese Fragen scheinen sich mit Programmen zu befassen, die sich als ein paar Dutzend Megabyte darstellen. Mein Programm zeigt fast 500MB , was viel besorgniserregender aussieht.

Ich kann mir nicht vorstellen, dass das alles von oben ist; Warum gibt es eine so große Diskrepanz zwischen dem VS-Profiler und dem Task-Manager?

Aktualisieren : Interessanterweise bleibt die Zahl im Task-Manager unter 10 MB, wenn ich einen Teil von InitializeComponent () auszählen lasse, der die ImageLists einrichtet. Ich habe zwei Gruppen von PictureBoxen und ImageLists, wobei die PictureBox eines von vier Bildern anzeigt, abhängig davon, welches Optionsfeld in einer Optionsfeldgruppe ausgewählt ist.

Diese Codezeilen sind diejenigen, die den massiven Speicherzuwachs auszulösen scheinen:

%Vor%

Ich verwende Bildlisten, damit ich Transparenz verwenden kann. Die Modusbilder sind 100x100 und belegen jeweils & lt; 26 KB Speicherplatz. Die Richtungsbilder sind standardmäßig 208 x 277 und ungefähr 75 KB auf der Festplatte. Ich weiß, dass png ein komprimiertes Format ist, aber selbst unkomprimiert im Speicher würde ich Hunderte von Megabyte für diese sieben Bilder nicht erwarten.

Gibt es eine gewisse Ineffizienz, die mir bekannt ist, und gibt es eine alternative Möglichkeit, Bilder mit Transparenz dynamisch anzuzeigen?

Fazit: Etwas ist mit der ImageList-Klasse fischig. Manchmal verliert es den Alpha-Kanal, und es hat dazu geführt, dass mein Programm viel mehr Speicher reserviert hat als benötigt. Es verlangsamte auch die Zeit, um das Hauptformular anfänglich zu zeichnen (sowohl beim Laufen als auch im Designer).

Durch das Auslagern der beiden ImageLists wurde mein Programm auf 10 MB RAM reduziert. Danke für all die Vorschläge alle!

    
Troyen 13.04.2011, 23:28
quelle

5 Antworten

0

png's haben schon Transparenz. Machen Sie dem Weiß eine transparente Farbe und speichern Sie das Bild. Dann benutze sie normal.

    
The Lazy Coder 14.04.2011, 00:50
quelle
2

Meine eigene Erfahrung mit diesem Problem ist, dass ich 24-Bit-Bilder in meiner Bildliste hatte, während ich die 32-Bit-Option in den Einstellungen der Bildliste eingestellt hatte.

Ich habe 24bit in den Eigenschaften der Bildliste eingestellt und das Problem ist weg. Das scheint ein Bug zu sein, den jemand auf MS =)

schreiben sollte

Entschuldigung für mein Englisch.

    
Trudogooglik 14.12.2013 14:59
quelle
1

Das .Net-Framework wurde so konzipiert, dass es angesichts der verfügbaren Ressourcen so schnell wie möglich läuft. Die Anwendung wird weiterhin mehr und mehr Speicher verbrauchen, da sie angefordert wird (und sofort verfügbar ist) und nur losgelassen wird, wenn Sie den Garbage Collector speziell aufrufen oder wenn eine andere Anwendung die Ressourcen benötigt, die sie in den Griff bekommt.

Minimieren Sie die App und Sie sollten sehen, wie viel Speicher Ihre Anwendung verwendet.

Wenn Sie dann zurückgehen, um es zu verwenden, bleibt es im niedrigeren Ressourcenstatus, bis es wieder verwendet wird und verbraucht. Minimiere es erneut, um zu sehen, wie viel tatsächlich (nicht) wieder verwendet wird. Dies ist in das Speicherverwaltungssystem von .net Frameworks integriert.

    
The Lazy Coder 13.04.2011 23:33
quelle
1

Jemand erklärte einige Gründe, warum der Speicher von 34 MB auf 145 MB gesprungen ist: Suche nach dem wahren Speicherbedarf einer Windows-Anwendung

    
Priyank 13.04.2011 23:54
quelle
0

Zuerst haben Sie versucht, Debug Diag ? Es analysiert einen Speicherauszug Ihres Prozesses und gibt einige raffinierte Graphenspeicher, die Ihnen helfen könnten herauszufinden, wer all diesen Speicher zugewiesen hat.

Stellen Sie außerdem sicher, dass weder Ihre kompilierte .exe noch eine Ihrer referenzierten / geladenen Assemblys sehr groß ist - es ist durchaus möglich, dass alle ~ 500 MB nur DLLs geladen werden. Dies kann passieren, wenn (zum Beispiel) große Ressourcen in die Assembly eingebettet wurden.

    
Justin 13.04.2011 23:34
quelle

Tags und Links