Entwickler-Ecke
IO, XML und Registry - Speicher läuft voll
Christoph1972 - Sa 10.04.10 14:13
Titel: Speicher läuft voll
Hallo!
Asche über mein Haupt.
Ich habe eine Funktion mit der ich Images via FileStream „sicher“ lade, damit die Images nicht auf dem Laufwerk blockiert werden. Das habe ich wir folgt gelöst:
C#-Quelltext
1: 2: 3: 4: 5: 6: 7: 8: 9: 10: 11: 12:
| private Image LoadImageSave(string file) { if (!File.Exists(file)) return null;
Bitmap saveBitmap = null; using (FileStream fs = new FileStream(file, FileMode.Open)) { saveBitmap = new Bitmap(fs); } return (Image)saveBitmap; } |
Nun ist es aber so, das mit jedem Aufruf der Arbeitsspeicher voller wird, bis es zum Überlauf kommt.
Könnte mir mal jemand meinen Gedankenfehler aufzeigen? Ich komme einfach nicht drauf, was ich hier falsch mache.
Ach ja, der Funktionsaufruf sieht lediglich so aus:
picturBox.Image = LoadImageSave(Bild);
Kha - Sa 10.04.10 15:16
Das alte Image solltest du vor der Zuweisung lieber disposen ;) .
Christoph1972 - Sa 10.04.10 16:24
Hi,
das habe ich natürlich versucht, hat aber leider keine Auswirkung. Oder kann es sein, das es zulange dauert, bis der GC das Object tatsächlich freigibt?
Christoph1972 - Sa 10.04.10 16:57
Ich habe es unteranderem so versucht:
C#-Quelltext
1: 2: 3: 4: 5: 6:
| if (image != null) image.Dispose();
image = new Bitmap (LoadImageSave(file)); PicBox.Image = image; |
Ich verstehe das nicht......
An meiner Methode liegt es übrigens nicht. Das Problem besteht auch bei: BitMap test = new BitMap(file)
Christian S. - Sa 10.04.10 17:04
Das new Bitmap (LoadImageSave(file)) erzeugt doch noch ein Image zusätzlich zu dem, welches die Methode zurückgibt. Und letzteres wird nicht freigegeben.
Christoph1972 - Sa 10.04.10 17:14
Aber das letztere darf ja auch nicht freigegeben werden, da dieses ja verwendet wird.
[EDIT] auch ohne new besteht das Problem weiter. Also image = LoadImageSave(file).
Kha - Sa 10.04.10 17:58
C#-Quelltext
1: 2: 3: 4: 5: 6:
| while (true) { if (pictureBox1.Image != null) pictureBox1.Image.Dispose(); pictureBox1.Image = new Bitmap(@"C:\Users\Kha\Pictures\Wallpapers\28-01-2009.jpg"); } |
...und nichts passiert ;) . Ohne Dispose bin ich schnell bei 1GB.
Christoph1972 hat folgendes geschrieben : |
Oder kann es sein, das es zulange dauert, bis der GC das Object tatsächlich freigibt? |
IDisposable und GC haben nichts miteinander zu tun... als Notfallleine ruft der Finalizer aber dann doch lieber noch Dispose auf, sollte es der Programmierer vergessen haben :) .
Christoph1972 - Sa 10.04.10 18:25
Also, ich bin auch mit Dispose schnell bei 1GB. Ich verstehe das nicht, mein Code ist jetzt identisch mit deinem, nur das ich das Image aus meiner Funktion lade.
Christoph1972 - Sa 10.04.10 18:28
Prima, ich habe herausgefunden, das es mit dem Format des Bilses zu tun hat. Wenn ich ein gif lade ist alles Ok, aber bei einer Verktorgrafik vom Typ emf läuft der Speicher voll......
Christoph1972 - Sa 10.04.10 20:06
So, alles OK. Ich hatte garnicht mehr geschaut ob es tatsächlich einen Überlauf gibt, ich hatte immer nur den Ram-Chart im Auge. Durch die großen EMF-Files ist der Verbrauch an Arbeitsspeicher groß, aber spätesten kurz vor knapp wird aufgeräumt. Ich hätte nicht gedacht, das es nötig ist das zugewiesene Image einer PictureBox zu disposen, da ich davon ausgegangen bin, das es überschrieben wird. Ich sollte älte Projekte noch mal durchsehen........
Vielen Dank euch!
Christoph1972 - So 11.04.10 11:25
Sorry, ich muss das leider zurücknehmen. Hin und wieder kommt es zu einem Überlauf. Das darf doch nicht sein, oder? Ich finde es auch seltsam, das der User das aktuelle Image disposen "soll", in der Dokumentation wird das nicht erwähnt. In meinen Augen wäre das schlecht programmiert. Wenn ich dem User ein Property zur verfügung stelle, das ein Überlauf verurschachen kann, dann würde ich das als Entwickler im Setter abfangen. Zudem macht es keinen sinn, das alte Image Objekt zu erhalten, oder?
Und weiter versuchen...........
Kha - So 11.04.10 12:40
Christoph1972 hat folgendes geschrieben : |
Das darf doch nicht sein, oder? |
Hm, im Zweifelsfall hast du ein EMF-Memory-Leak in GDI+ getroffen :( .
Christoph1972 hat folgendes geschrieben : |
Wenn ich dem User ein Property zur verfügung stelle, das ein Überlauf verurschachen kann |
Den Überlauf "verursachen" tut ja wohl eher der Bitmap-Konstruktor, und bei Bitmap als IDisposable müssen die Alarmglocken schrillen.
Christoph1972 hat folgendes geschrieben : |
Zudem macht es keinen sinn, das alte Image Objekt zu erhalten, oder? |
Wie wäre es zum Beispiel mit einem simplen Wechsel zwischen zwei Bitmaps? Kann die PictureBox nicht wissen, also soll sie sich heraushalten.
Christoph1972 - So 11.04.10 20:46
Hi, der Überlauf ist nicht reproduzierbar. Na ja, ich hoffe das es eine unglücklich Verkettung von Ereignissen war und das Problem nicht wieder auftritt. Bisher bin ich immer achtlos mit Image Objekten umgegangen, das wird seit diesem Thread anders sein. Immer schön disposen :wink:
Also, vielen Dank für die hilfreiche Unterstützung!
Ach ja, eigentlich gehört das nach Grafik/Multimedia verschoben, hatte ja nichts mit meinem Stream zu tun.
Entwickler-Ecke.de based on phpBB
Copyright 2002 - 2011 by Tino Teuber, Copyright 2011 - 2025 by Christian Stelzmann Alle Rechte vorbehalten.
Alle Beiträge stammen von dritten Personen und dürfen geltendes Recht nicht verletzen.
Entwickler-Ecke und die zugehörigen Webseiten distanzieren sich ausdrücklich von Fremdinhalten jeglicher Art!