Laden...

Speicherverbrauch explodiert beim Laden von Bildern

Erstellt von inva vor 12 Jahren Letzter Beitrag vor 12 Jahren 3.967 Views
I
inva Themenstarter:in
37 Beiträge seit 2007
vor 12 Jahren
Speicherverbrauch explodiert beim Laden von Bildern

Hallo Community,
Ich möchte gern ein ListView mit einer ImageList erstellen und diese anzeigen.
Jedoch habe ich dabei das Problem, dass der Speicherverbrauch (RAM) bereits bei einem geladenem Bild (~3MB) auf 53 MB (vor dem Laden: 17MB) steigt.

Anbei mein Code:


private void AddImage(string sFilePath)
        {
            Image newImage = Image.FromFile(sFilePath);// Viele Bilder: OutOfMemory Exception
            newImage.Tag = GetFileNameFromPath(sFilePath);

            imageList.Images.Add(newImage.Tag.ToString(), newImage);
            lPathsOfImagesToScale.Add(sFilePath);

            ListViewItem currentItem = new ListViewItem(sFilePath);
            currentItem.ImageIndex = imageList.Images.Count - 1;
            ctrlImagePreviewBox.Items.Add(currentItem);

            newImage = null;
        }

Der Speicherverbrauch schnellt an der Stelle


Image newImage = Image.FromFile(sFilePath);

wie oben beschrieben in die Höhe.

Bzgl. "Bildverarbeitung" bin ich leider noch ein absoluter Anfänger und ich habe das Laden der Bilder auf die einfachste Art und Weise implementiert und möchte es gern optimieren.
Leider weiß ich nicht, wie optimierbar der Code noch ist, da ich das Bild ja nicht irgendwann wieder freigebe, sondern ein Verweis darauf stetig in der ImageList hinterlegt ist.

Ideen? Vorschläge?

Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.

1.029 Beiträge seit 2010
vor 12 Jahren

Hi,

zuerstmal: Dein Bild ist zu groß. Speicher und lad es entsprechend der in der ImageList gespeicherten Größe - das dürfte ein wenig helfen.

Was Images laden über die von dir verwendete Methode angeht habe ich
schleche Erfahrungen gemacht.

Kam bei der Arbeit des Öfteren zu GDI+ Exceptions - angeblich wegen irgendwelcher Locks...

Ich les Bilder wenn ich diese selbst lade in ein byte-Array und zaubere dann daraus ein Bild.

Woran dieser enorme Speicherzuwachs genau liegt... kA...

Zudem bietet die ImageList an eine niedrigere Qualität für Bilder zu verwenden - wann das geschieht wäre interessant - möglich wäre, dass die ImageList dein Bild z.B. sogar noch mal kopiert und dein eigentliches Bild unnötig macht...

Das wärn die paar Sachen die mir dazu einfallen.

LG
Achim

2.298 Beiträge seit 2010
vor 12 Jahren

Woran dieser enorme Speicherzuwachs genau liegt... kA...

Das wird wohl daran liegen, dass das Bild im Arbeitsspeicher verschwindet? 😉

Wissen ist nicht alles. Man muss es auch anwenden können.

PS Fritz!Box API - TR-064 Schnittstelle | PS EventLogManager |

1.029 Beiträge seit 2010
vor 12 Jahren

Hi,

Bei 3/6 oder sogar 9 MB sicherlich gerne am Bild inkl. 1 oder 2 Kppien 😉

Da wir hier allerdings doch von ein wenig mehr reden kann das (eig) nicht (nur) am bild liegen.

So denk ich jedenfalls...

LG
Achim

Gelöschter Account
vor 12 Jahren

Sry wenn ich euch alle enttäuschen muss aber das liegt höchst wahrscheinlich am Memorymanagement der CLR und nicht an dem Tatsächlichen Verbrauch des Bildes.

Vorab eine Frage: diesen "Anstieg" hast du im Taskmanager beobachtet?

I
inva Themenstarter:in
37 Beiträge seit 2007
vor 12 Jahren

Hi,
zuerstmal: Dein Bild ist zu groß. Speicher und lad es entsprechend der in der ImageList gespeicherten Größe - das dürfte ein wenig helfen.

Danke, ich werde mir dann wohl eine kleine Thumbnail Methode Stricken, oder gibt es im.NET Framework bereits eine Methode die diese Funktion implementiert?

Vorab eine Frage: diesen "Anstieg" hast du im Taskmanager beobachtet?

Jep - ist das nicht aussagekräftig genug? Mein Problem ist, dass ich diesen Aufruf für mehrere Bilder in einer Schleife mache. Das führt dann irgendwann dazu, dass ich von genau dieser Stelle eine OutOfMemoryException geworfen bekomme.

Ich kann mir nicht so recht vorstellen, warum die ImageList sich Kopien erstellen sollte, aber nichts desto trotz. Gebe ich das Image Objekt explizit mit Dispose() wieder frei erscheinen die Bilder auch nicht mehr in der ImageList.
Der Speicherverbrauch steigt auch nicht beim Zuweisen des Image Objekts an de ImageList so stark an, sondern beim Aufruf von Image.FromFile(...).

Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.

Gelöschter Account
vor 12 Jahren

ich werde mir dann wohl eine kleine Thumbnail Methode Stricken, oder gibt es im.NET Framework bereits eine Methode die diese Funktion implementiert?

Ja, gibt es.

Jep - ist das nicht aussagekräftig genug?

Jep. Vergiss den Taskmanager, wenn du mit .NET den Speicherverbrauch messen willst.

Das führt dann irgendwann dazu, dass ich von genau dieser Stelle eine OutOfMemoryException geworfen bekomme.

Die Bilder liegen natürlich in ihrer Origianlgröße im Arbeitsspeicher. Da sie vermutlich mehr als die 85k Speicher verfressen, liegen die auch noch im LOH, was sich auch negativ auf die effektivität des Speichermanagements auswirkt.

Wieviel in MB sind denn alle Bilder zusammen, die du laden willst?

I
inva Themenstarter:in
37 Beiträge seit 2007
vor 12 Jahren

Wieviel in MB sind denn alle Bilder zusammen, die du laden willst?

Es können schon (weit) über 100 MB zusammen sein.

Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.

49.485 Beiträge seit 2005
vor 12 Jahren

Hallo inva,

Es können schon (weit) über 100 MB zusammen sein.

100 MB (JPEG-/PNG-)komprimiert oder 100 MB entkomprimiert?

Ist aber eigentlich auch egal, denn die Lösung wurde ja schon genannt.

herbivore

Gelöschter Account
vor 12 Jahren

100 MB sind kein Problem. Mehr als 2 GB könnten problematisch sein.
Wieviele Bilder sind es in etwa? Hintergrund ist, das es prinzipiell 2 Möglichkeiten für diese Exceptions gibt. RAM oder das überlaufen des GDI Stacks.

I
inva Themenstarter:in
37 Beiträge seit 2007
vor 12 Jahren

2 GB könnten auch vorkommen - im ersten Fall könnte ich eventuelle Referenzen wieder freigeben und bei Bedarf neu allokieren.

Aber, was ich mich frage, wie macht es der Windows Explorer? Er verfügt ja auch über eine Miniaturansicht, und selbst wenn x-beliebig viele Bilder in einem Ordner sind, zeigt er brav alle an, er lädt sie zwar erst in dem Moment, wenn ich sie scrolle, aber einmal geladen sind sie persistent in der Miniaturansicht. Ich wollte prinzipiell das gleiche Verhalten wie die Windows Explorer Miniaturansicht implementieren (aber erstmal ohne das Laden bei Bedarf).

Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.

6.911 Beiträge seit 2009
vor 12 Jahren

Hallo,

der Explorer zeigt ja als Miniaturansicht nicht das Originalbild sondern ein Thumbnail-Image davon an (also ein kleines Bild). Daher auch die versteckte thumbs.db Datei indem Ordner wo diese gecached werden.

mfG Gü

Stellt fachliche Fragen bitte im Forum, damit von den Antworten alle profitieren. Daher beantworte ich solche Fragen nicht per PM.

"Alle sagten, das geht nicht! Dann kam einer, der wusste das nicht - und hat's gemacht!"

5.742 Beiträge seit 2007
vor 12 Jahren

Vielleicht um das nochmal explizit zu erwähnen: Wirf die Bilder möglichst schnell wieder aus dem Speicher (mittels Dispose bzw. using) und halte nur ein Thumbnail im Speicher, das du via GetThumbnailImage erzeugst.

Für die Thumbs.db gibt's zwar Parser auf Codeproject, sie existiert aber nur unter XP - Vista / 7 haben da eine andere Datei.

4.221 Beiträge seit 2005
vor 12 Jahren

Hier ist meine GetThumbnail-Methode drin.

ImageListBox

Früher war ich unentschlossen, heute bin ich mir da nicht mehr so sicher...

I
inva Themenstarter:in
37 Beiträge seit 2007
vor 12 Jahren

der Explorer zeigt ja als Miniaturansicht nicht das Originalbild sondern ein Thumbnail-Image davon an (also ein kleines Bild). Daher auch die versteckte thumbs.db Datei indem Ordner wo diese gecached werden.

D.h. dann doch aber, dass ich, wenn ich nur genügend Bilder in einem Ordner habe, auch im Explorer eine OutOfMemoryException produzieren könnte?

Vielen Dank an euch!
Die Idee bzgl. der Thumbnails werde ich aufgreifen. Ich dachte ich mache eventuell generell etwas falsch oder es gibt einen effizienteren Weg - aber eigentlich hätte ich da auch selber drauf kommen können. Nichts desto trotz, vielen Dank! 😃

Aller Wahrscheinlichkeit nach wird das Weltall von einem Rudel Irrer regiert.

5.742 Beiträge seit 2007
vor 12 Jahren

D.h. dann doch aber, dass ich, wenn ich nur genügend Bilder in einem Ordner habe, auch im Explorer eine OutOfMemoryException produzieren könnte?

Unwahrscheinlich - der Explorer entlädt auch Thumbnails, die er nicht braucht, wieder.