2009-10-08 12 views
7

Vor einiger Zeit habe ich eine Frage zu einem WriteableBitmap-Speicherleck gestellt, und obwohl ich wunderbare Tipps in Bezug auf das Problem erhalten habe, denke ich immer noch, dass es einen ernsthaften Fehler gibt (von mir gemacht)/(Confusion)/(etwas anderes) hier.Wie man eine beschreibbare Bitmap entsorgen kann? (WPF)

So, hier ist mein Problem wieder:

Angenommen, wir haben eine WPF-Anwendung mit einem Bild und einem Knopf. Die Quelle des Bildes ist eine wirklich große Bitmap (3600 * 4800 px), wenn es zur Laufzeit angezeigt wird, verbraucht die Anwendung ~ 90 MB.

Nun nehme ich an, ich möchte ein WriteableBitmap aus der Quelle des Bildes (das wirklich große Bild) instanziieren, wenn dies geschieht, verbraucht die Anwendungen ~ 220 MB.

Jetzt kommt der schwierige Teil, wenn die Änderungen am Bild (durch die WriteableBitmap) enden, und alle Verweise auf die WriteableBitmap (zumindest diejenigen, die ich kenne) zerstört werden (am Ende einer Methode) oder indem Sie sie auf null setzen) sollte der von writeableBitmap verwendete Speicher freigegeben werden und die Anwendungskonsum sollte auf ~ 90 MB zurückkehren. Das Problem ist, dass es manchmal zurückkehrt, manchmal nicht.

Hier ist ein Beispielcode:

// The Image's source whas set previous to this event 
private void buttonTest_Click(object sender, RoutedEventArgs e) 
    { 
     if (image.Source != null) 
     { 
      WriteableBitmap bitmap = new WriteableBitmap((BitmapSource)image.Source); 

      bitmap.Lock(); 

      bitmap.Unlock(); 

      //image.Source = null; 
      bitmap = null; 
     } 
    } 

Wie Sie die Referenz am Ende des Verfahrens lokal ist und der Speicher sehen können soll (oder wenn der Garbage Collector entscheidet zu tun) freigegeben werden. Die App könnte jedoch bis zum Ende des Universums ca. 224 MB verbrauchen.

Jede Hilfe wäre großartig.

Antwort

0

Muss das Bitmap-Bild mit derselben Auflösung und denselben Pixeln gerendert werden? Sie könnten die Writablebitmap mit einem viel niedrigeren Satz von Pixeln erstellen und die Rendermethode aufrufen. Da die Writeable Bitmap beim Aufruf von render einen Verweis auf die ursprünglichen Uielements enthält, haben Sie in diesem Fall 3 Chunks: 1) Originalelement, 2) Pixel in Writeable Bitmap, 3) Referenz auf kopiertes Original.

Ich hatte ein ähnliches Problem mit dem Writeablebitmap in Bezug auf Speicherlecks und ich regelte es von diesem Link Check-out: http://www.wintellect.com/CS/blogs/jprosise/archive/2009/12/17/silverlight-s-big-image-problem-and-what-you-can-do-about-it.aspx

Wenn Sie einen anderen Writeablebitmap erstellen und die Pixel über kopieren, dann entsorgen Sie den ersten Writeablebitmap Sie sollten eine Speicherfreigabe sehen - zumindest habe ich das in meinem Szenario gemacht.