WPF-Ausnahme wegen zu wenig Arbeitsspeicher beim Laden einer großen Anzahl von Bitmaps in einer einzelnen Instanz der App. Gibt es eine Grenze?

8

Ich muss große Mengen an Bitmaps zur Anzeige in einer WPF-App in den Speicher laden (mit .net 4.0). Wo ich auf Probleme stoße, betrachte ich etwa 1.400 MB Arbeitsspeicher (ich bekomme das aus der Prozessliste im Task-Manager).

Das Gleiche passiert, wenn die App auf einem Computer mit 4 GB Arbeitsspeicher oder 6 GB ausgeführt wird (und einigen anderen Konfigurationen, auf denen ich die Details nicht habe). Es ist einfach zu testen, indem die geladenen Bilder reduziert werden und wenn es auf 1 Maschine funktioniert, dann funktioniert es auf allen, aber wenn es auf einem abstürzt, tut es auch alles.

Wenn ich die Anzahl der Bilder reduziere und erlaube, dass die App geladen wird, ohne die Speicherausnahme zu verursachen, kann ich mehrere Instanzen der App ausführen (die 1,4 GB der einzelnen Instanz überschreiten), ohne das Problem zu haben oder pro Instanz Fehler meinerseits.

Ich lade die Bilder als BitmapImage und sie werden entweder in einem List<BitmapImage> gespeichert oder in ein List<byte[]> geladen, wo sie später in einer Reihe von geschichteten Sequenzen verwendet werden (mit Writeablebitmap )

Der Fehler tritt auf, wenn ich die Bilder nicht während der Verwendung lade. Im wiederholbaren Fall lade ich 600 640x640 Bilder plus weitere 200-300 kleinere Bilder im Bereich von 100x100 bis 200x200, obwohl es anscheinend eine Gesamtbitzahl ist, die das Problem ist.

Meine Fragen sind also:

* Gibt es in einer Situation wie dieser eine pro Prozessspeichergrenze?

* Gibt es eine bessere Technik, um große Mengen von Bilddaten in den Speicher zu laden?

Danke, Brian

    
Brian 12.10.2010, 03:52
quelle

4 Antworten

11

Ja, pro Prozessspeicherzuweisung gibt es eine Begrenzung. Eine der Lösungen besteht darin, Ihre binäre LARGEADDRESSAWARE dazu zu bringen, mehr Speicher zu verbrauchen.

Siehe Nicht genügend Arbeitsspeicher? Einfache Möglichkeiten, um den Speicher für Ihr Programm zu erhöhen , es gibt große Diskussion um Lösungen dafür.

    
Arun M 12.10.2010, 04:29
quelle
3

Unten kann eine Ursache sein, aber ich bin mir nicht sicher

Bei dem Problem geht es nicht um das Laden großer Datenmengen, sondern weil CLR einen großen Heap für ein Objekt mit mehr als 85.000 Arbeitsspeicher verwaltet und Sie keine Kontrolle haben, um diesen großen Heap freizugeben.

und diese Objekte wurden zu "Long Lived" und werden normalerweise freigegeben, wenn Appdomain Unloads.

Ich würde vorschlagen, dass Sie versuchen, größere Bilder in einer anderen AppDomain zu laden und diese Appdomain zu verwenden, um größere Bilder zu manuplizieren.

Siehe MSDN-Eintrag für Profiling-GC

Sehen Sie, ob Memory Mapped Files hilft, falls Sie .net 4.0

Und mehr Beispiel

    
TalentTuner 12.10.2010 04:02
quelle
1

Ein x86-Build kann unter 64-Bit-Windows auf 4 GB zugreifen, das ist also die theoretische Obergrenze für den Prozess. Dies erfordert, dass die Anwendung große Adressdaten enthält. Darüber hinaus gibt .NET ein Limit von 2 GB für ein einzelnes Objekt an.

Sie leiden möglicherweise an LOH Fragmentierung. Objekte, die größer als 85000 Byte sind, werden auf dem Large Object Heap gespeichert, einem speziellen Teil des verwalteten Heapspeichers, der nicht komprimiert wird.

Sie sagen, dass die Bilder 600x600 sind, aber was ist das Pixelformat und gibt es auch eine Maske? Wenn Sie ein Byte pro Farbkanal plus ein Byte für den Alphakanal verwenden, beträgt jedes Bild 600x600x32. Daher ist das Problem, 600 davon gleichzeitig zu laden, ein Problem in einem 32-Bit-Prozess.

    
Brian Rasmussen 12.10.2010 04:24
quelle
0

Sie stoßen auf die 32-Bit-Begrenzungsvorgänge, die nur auf etwa 2 GB Daten zugreifen können. Wenn Sie 64 Bit ausführen würden, hätten Sie die Probleme nicht. Es gibt eine Reihe von Möglichkeiten, um das Problem zu umgehen, von denen einige sind:

  • Laden Sie einfach nicht so viele Daten, laden Sie sie nur bei Bedarf. Verwenden Sie das Zwischenspeichern.
  • Verwenden Sie Speicherabbilddateien, um ganze Datenschächte in den Speicher abzubilden. Nicht empfohlen, da Sie die gesamte Speicherverwaltung selbst durchführen müssen.
  • Verwenden Sie mehrere Prozesse, um die Daten zu speichern, und verwenden Sie einen IPC-Mechanismus, um nur die benötigten Daten zu übertragen, ähnlich wie in Punkt 1.
Joel Lucsy 12.10.2010 04:28
quelle

Tags und Links