Forum: PC-Programmierung Extremer Speicherverbrauch WPF/C#


von Markus D. (emtec)


Lesenswert?

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, 
daß 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

von Bernd (Gast)


Lesenswert?

Kann es sein dass du BMP-Bilder eingebunden hast?
Wenn ja, versuchs dich mit PNG (Bei Piktogrammen) oder JPG (Bei Fotos)

von Markus D. (emtec)


Lesenswert?

Hallo,

nein es sind alles ausschließlich PNG/JPEG Dateien.
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!?

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

: Bearbeitet durch User
von plauz (Gast)


Lesenswert?

K.A., aber evtl. mal so etwas (oder draran angelehnt) ausprobieren:
1
public static System.Windows.Media.Brush CreateBrushFromBitmap(Bitmap bmp)
2
{
3
  IntPtr hBitMap = bmp.GetHbitmap();
4
  ImageBrush b = new ImageBrush(Imaging.CreateBitmapSourceFromHBitmap(hBitMap, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions()));
5
  DeleteObject(hBitMap);
6
  return b;
7
}

von bluppdidupp (Gast)


Lesenswert?

Wie groß sind die Grafiken denn (in Pixeln) und wie häufig werden sie 
geladen?
Werden die Grafiken skaliert?

von Sebastian__ (Gast)


Lesenswert?

Jedes MAl wenn du dein Bild instanzierst wird es NEU in den Speicher 
geladen.
Bilder kann man Freezen wenn man die wiederverwenden möchsten.

Von Microsoft gibt es für WPF recht ausführliche Performance Guidelines 
an die man sich halten kann.

von Markus D. (emtec)


Lesenswert?

Hallo,

ich habe den Fehler mittlerweile gefunden. Der Fehler lag darin, daß die 
ursprünglich verwendeten Bilder knapp 500KiB groß waren. Beim erstellen 
des ImageBrush wurde durch das große Bildformat und die hohe 
Bildqualität enorm viel Speicher alloziert. Pro Bild ca. 100MiB!!

Ein neuskalieren auf kleinere Dimensionen sowie eine höhere 
Bildkompression haben das Problem dann gelöst, sodaß der Speicherbedarf 
der Anwendung jetzt "nur" noch rund 70 MiB beträgt. Die selbe Anwendung 
hatte ich vor ein paar Jahren mit Delphi 7 umgesetzt und der 
Speicherverbrauch des Programms zur Laufzeit lag bei knapp 10 MiB!

Grüße

von Peter II (Gast)


Lesenswert?

Was sind das für Bilder?

ein PNG bild mit 1200 x 1024 ist 200kbyte groß. Machst du etwa FullHD 
Bilder auf deine Buttons?

dafür verwendet man doch maximal 200x200 Pixel und dann kommt mal auf 
weniger als 10kbyte.

Ich denke es liegt mehr an euch als ans C# das der Speicherverbrauch so 
hoch ist.

von Halbhonk (Gast)


Lesenswert?

Peter II schrieb:
> ein PNG bild mit 1200 x 1024 ist 200kbyte groß

Aber auch nur auf der Festplatte ... Sonst bei 24 Bit >= 3,5MB. Das 
Ursprungsformat spielt im RAM ja keine Rolle mehr.

von Peter II (Gast)


Lesenswert?

Halbhonk schrieb:
> Aber auch nur auf der Festplatte ... Sonst bei 24 Bit >= 3,5MB. Das
> Ursprungsformat spielt im RAM ja keine Rolle mehr.

es muss nicht entpackt im Ram liegen, die Grafikkarte kann auch einige 
Formate selber dekodieren.

von lolalter (Gast)


Lesenswert?

C#/.NET ist ja mindestens genauso schnell und leichtgewichtig wie C++.
Jaja liebe MS Fans, da sieht man wieder wie lahm C# ist, haha!

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.