Laden...

Extremer Speicherverbrauch WPF/C#

Erstellt von priva80 vor 10 Jahren Letzter Beitrag vor 10 Jahren 2.068 Views
P
priva80 Themenstarter:in
8 Beiträge seit 2013
vor 10 Jahren
Extremer Speicherverbrauch WPF/C#

Hallo,

ich entwickle zur Zeit mit Ms-VS 2012 Professional eine technische Software. Kurz gesagt sollen Anwender ohne spezielle Schulung in der Lage sein, das Programm zu bedienen. Daher habe ich möglichst viele Sinnbilder (ca. 30 in Resourcendatei - eingebettet- ) für komplexe Operation verwendet, die sogar ein Gehirnamputierter nicht fehlinterpretieren kann. Ein Blick in den Resourcenmonitor hat mir gerde den Tag versaut, denn die gesamte Anwendung verbraucht jetzt schon rund 600 MiB an Speicherplatz. Bei der Fehlersuche ist mir dann Aufgefallen, das dies tatsächlich an den als Typ Resource eingebundenen Bildern liegt!? Wenn ich kurzer Hand alle lösche, schrumpft der Speicherverbrauch auf - für heutige Zeiten - vertretbare 60 MiB. Also fasst 10mal weniger! Hat jemand eine Erklärung dafür bzw. einen Tip wie ich den Speicherverbrauch der Anwendung in einen normalen Bereich bringe?

Viele Grüße

W
955 Beiträge seit 2010
vor 10 Jahren

Hi,

* wie groß sind denn diese "Sinnbilder"?
* hast Du das mit einem MemoryProfiler geprüft oder nur im TaskManager geschaut?

P
priva80 Themenstarter:in
8 Beiträge seit 2013
vor 10 Jahren

Hallo,

  • wie groß sind denn diese "Sinnbilder"?

Unterschiedlich, da ich manche aus qualitativen Gründen aufwendig nachbessern musste. Einfache Bilder normal, also wenige KiB groß. Ein paar musste ich allerdings nahezu ohne Bildkompression aufnehmen. Die haben dann vieleicht zwischen 300 und 600 KiB. Wenn du's genau wissen willst, siehe "screen shot" im Anhang.

  • hast Du das mit einem MemoryProfiler geprüft oder nur im TaskManager geschaut?

Nein, bisher habe ich nur im Taskmanager/Resourcenmonitor nachgesehen. Welchen MemProfiler kannst du empfehlen? Mit einem solchen Problem war ich bisher noch nicht konfrontiert!

Grüße

W
955 Beiträge seit 2010
vor 10 Jahren

So klein sind die Grafiken aber nicht.
Du könntest Dir mal den ANTS Memory Profiler anschauen (Demoversion ist kostenlos). Sinn der Übung ist es, rauszukriegen ob
* der GC einfach den Speicher nicht freigeräumt hat weil noch genügend Betriebsmittel zur Verfügung stehen
* die Ressourcen nicht weggeräumt werden weil noch irgendetwas auf diese Ressourcen zeig
* ob für dieselbe Grafik/Ressource dennoch mehrere Kopien verwendet werden

P
priva80 Themenstarter:in
8 Beiträge seit 2013
vor 10 Jahren

Hallo,

ich habe den Fehler jetzt zurückverfolgt. Es liegt tatsächlich nur an
vier Bildern, die in vier Steuerelementen vom Typ Boder als Background
festgelegt sind. Eine Idee warum vier einzelne JPEG-Bilder rund 500 MiB
Speicher verbrauchen?

Auch wenn in der Code-behind Datei ein einzelnes Bild manuell als Border
Hintergrund lade, steigt sofort der Speicherverbrauch um ca. 100MiB!?


borderStandartNpt.Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/GCodeGenerator;component/Resources/NPTkeinEingriff.jpg")));

Z
403 Beiträge seit 2007
vor 10 Jahren

Hallo priva80,

vermutlich ist es hiermit gelöst: Memory leak loading imagebrush - Stackoverflow

André

P
priva80 Themenstarter:in
8 Beiträge seit 2013
vor 10 Jahren

Ok, kann sein!

Scheinbar haben schon andere das Problem gehabt. Trotzdem bekomm ich es nicht hin.



        public static System.Windows.Media.Brush CreateBrushFromBitmap(Bitmap bmp)
        {
            return new System.Windows.Media.ImageBrush(System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(bmp.GetHbitmap(), IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()));

        }

        private void borderStandartGewinde_MouseEnter(object sender, MouseEventArgs e)
        {
            try
            {
                borderStandartGewinde.Opacity = stdBBrightness.high;
              // borderStandartGewinde.Background = new ImageBrush(new BitmapImage(new Uri(@"pack://application:,,,/GCodeGenerator;component/Resources/StandardImEingriff.jpg"))); //bisherige Methode mit memory leak
                borderStandartGewinde.Background =  CreateBrushFromBitmap(new BitmapImage(new Uri(@"pack://application:,,,/GCodeGenerator;component/Resources/StandardImEingriff.jpg")));
            }

            catch
            { /*keine Fehlerbehandlung aber evtl. Fehler abfangen*/  }
        }

Dann erhalte ich die Fehler :

Fehler 8 Die beste Übereinstimmung für die überladene 'GCodeGenerator.MainWindow.CreateBrushFromBitmap(System.Drawing.Bitmap)'-Methode hat einige ungültige Argumente. C:\Users\priva\Documents\Visual Studio 2012\Projects\C#\WPF\GCodeGenerator\GCodeGenerator\MainWindow.xaml.cs 283 53 GCodeGenerator

Fehler 9 Argument '1': Konvertierung von 'System.Windows.Media.Imaging.BitmapImage' in 'System.Drawing.Bitmap' nicht möglich. C:\Users\priva\Documents\Visual Studio 2012\Projects\C#\WPF\GCodeGenerator\GCodeGenerator\MainWindow.xaml.cs 283 75 GCodeGenerator

EDIT: Fehler gefunden