none
Was passiert eigentlich im Speicher wenn ich eine Bitmap mit neuer Auflösung erstelle? RRS feed

  • Frage

  • Hallo.
    Ich hoffe das ist das richtige Forum, hab kein wirklich passendes gefunden.

    Was passiert eigentlich im Speicher, wenn ich eine Bitmap mit einer anderen Auflösung erstelle?
    In dem Stil ->
    Bitmap b1 = new Bitmap(<pfad zu Datei>);
    Bitmap b2 = new Bitmap(b1, x, y); // wobei x und y das Bild kleiner machen als das Original

    Der Grund für die Frage ist ein Control, dass ich gerade mit C# schreibe. Wenn ich viele Bilder einer höheren Auflösung öffne wird wesentlich mehr Speicher verbraucht als bei Bildern mit einer geringeren Auflösung, obwohl beide auf maximal 384x384 Pixel verkleiner werden.
    Die Vorschaubilder selber erklären den Speicherbedarf nicht:
    384 Pixel * 384 Pixel * 4 Byte * max. 30 geladene Bilder (die gesamte Liste enthielt 534 Elemente, die jeweils 1 String, 1 int und eine auf null referenzierte Bitmap beinhalteten (bei den 30 erwähnten war die nicht null)), das macht etwa 18MB theoretischer Speicherbedarf, realer Speicherbedarf liegt bei mindestens 100MB, je nachdem wie er grade lustig ist auch mal bei 200 oder 300.
    Hab mal spaßeshalber alle Bilder auf meinem Rechner in die Liste geladen (17'000+), wenn ich da die großen aufsuche hab ich die selben Speicherprobleme, wenn ich mir stattdessen kleiner ansehe liegt der Speicherbedarf üblicherweise unter 50MB.

    Woran liegt das?
    Dienstag, 17. Juni 2008 14:56

Antworten

  •  

    >>Ich hoffe das ist das richtige Forum, hab kein wirklich passendes gefunden.
    Das wird sich hier auch noch nicht so schnell ändern. Ich finde es auch besser, wenn ein Forum wirklich im Betrieb ist, anstelle von 50 oder mehr Foren, wo man gleich die Übersicht verliert. Vergleiche MSDN Forum Englisch. Das ist der absolute Wahnsinn. Soetwas kann keiner warten und Überblicken.

     

    Zu deinem Problem. Bedenke die .Net Platform. Erst einmal muss das ganze Bild in den Speicher geladen werden und dann kann es verkleinert werden. Das kostet "sehr viel" Rechenzeit (bei großer Menge > 1000). Wahrscheinlich räumst Du danach nicht per Hand auf (Null-Referenzierung). d.h. der GC muss her und dieser lässt sich ein wenig Zeit und geht öfters auf Nummer sicher. Außerdem dauert das ziemlich lange, bis er einen solchen Datenhaufen geordnet hat.

    Fazit: Wenn Du unbedingt so viele Bilder benötigst dann versuche doch eine Suche zu integrieren und lade die Bilder dann gleich ohne weitere Anpassung. Das zieht dann auf die Dauer mehr Speicher, aber zugleich, kannst Du besser arbeiten und bei ein paar Bildern bleibt das vor allem überschaubar und hält sich in Grenzen. Mehr kann ich hier nicht sagen. Ich kann eben nur Vermutungen anstellen.

    Dienstag, 17. Juni 2008 16:48

Alle Antworten

  •  

    >>Ich hoffe das ist das richtige Forum, hab kein wirklich passendes gefunden.
    Das wird sich hier auch noch nicht so schnell ändern. Ich finde es auch besser, wenn ein Forum wirklich im Betrieb ist, anstelle von 50 oder mehr Foren, wo man gleich die Übersicht verliert. Vergleiche MSDN Forum Englisch. Das ist der absolute Wahnsinn. Soetwas kann keiner warten und Überblicken.

     

    Zu deinem Problem. Bedenke die .Net Platform. Erst einmal muss das ganze Bild in den Speicher geladen werden und dann kann es verkleinert werden. Das kostet "sehr viel" Rechenzeit (bei großer Menge > 1000). Wahrscheinlich räumst Du danach nicht per Hand auf (Null-Referenzierung). d.h. der GC muss her und dieser lässt sich ein wenig Zeit und geht öfters auf Nummer sicher. Außerdem dauert das ziemlich lange, bis er einen solchen Datenhaufen geordnet hat.

    Fazit: Wenn Du unbedingt so viele Bilder benötigst dann versuche doch eine Suche zu integrieren und lade die Bilder dann gleich ohne weitere Anpassung. Das zieht dann auf die Dauer mehr Speicher, aber zugleich, kannst Du besser arbeiten und bei ein paar Bildern bleibt das vor allem überschaubar und hält sich in Grenzen. Mehr kann ich hier nicht sagen. Ich kann eben nur Vermutungen anstellen.

    Dienstag, 17. Juni 2008 16:48
  • Das ganze Funktioniert in etwa so: Elemente, die erstmal nur eine auf null referenzierte Bitmap enthalten, werden in eine Liste eingetragen.
    Einem Thread, der die ganze Zeit im Hintergrund läuft, wird gemeldet, dass es Arbeit gibt. Der holt sich die sichtbaren Indizes und prüft, ob deren Bitmap null ist. Ist das der Fall ruft er eine Funktion auf, die den String aus dem Element übernimmt, damit eine Bitmap öffnet und die verkleinerte Version dieser Bitmap zurück gibt. Die große Bitmap sollte nach Beendigung der Funktion schon ein Fall für den GC sein.
    Ein weiterer Thread setzt parallel die Bitmaps aller Elemente, die nicht angezeigt werden, auf null.

    Hab mit Deinen Vermutungen im Hinterkopf die Funktion, die die Vorschaubilder erstellt und zurück gibt ein wenig geändert, unter anderem auch dahin, dass ich auf das Original Bild Dispose() aufrufe, jetzt ist die maximale Speicherauslastung auf 70BM, durchschnittlich 50.
    Das ist zwar immernoch mehr als ich ausgerechnet habe, aber mit dem Wert kann ich leben.

    Darum: Danke für den richtigen Hinweis zur Lösung Smile
    Dienstag, 17. Juni 2008 17:40
  • Das geht doch schon. Es sind eben Bilder... Du könntet jetzt mit Codierung anfangen, aber das geht dann auf die CPU. ICh empfehle Dir das einfach so zu lassen.

     

    Mittwoch, 18. Juni 2008 18:21