2009-10-08 9 views
7

Jakiś czas temu napisałem pytanie związane z wyciekiem pamięci WriteableBitmap, i chociaż otrzymałem wspaniałe wskazówki związane z tym problemem, nadal uważam, że istnieje poważny błąd/(błąd popełniony przeze mnie)/(Confusion)/(jakieś inne) tutaj.Jak usunąć bitmapę do zapisu? (WPF)

Tak, tu jest mój problem ponownie:

Załóżmy, że mamy aplikację WPF z obrazem i przycisku. Źródłem obrazu jest naprawdę duża bitmapa (3600 * 4800 pikseli), gdy jest wyświetlana w czasie wykonywania aplikacji, zużywa ~ 90 MB.

Załóżmy teraz, że chcę utworzyć instancję WriteableBitmap ze źródła obrazu (naprawdę dużego obrazu), gdy tak się stanie, aplikacje zużywają ~ 220 MB.

Teraz jest najtrudniejsza część, gdy modyfikacje obrazu (poprzez WriteableBitmap) kończą się, a wszystkie odniesienia do WriteableBitmap (przynajmniej tych, które są świadome) zostaną zniszczone (na końcu metody) lub ustawiając je na wartość null) pamięć używana przez writeableBitmap powinna zostać zwolniona, a zużycie aplikacji powinno powrócić do ~ 90 MB. Problem polega na tym, że czasami wraca, czasem nie.

Oto przykładowy kod:

// 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; 
     } 
    } 

Jak widać odesłanie ma charakter lokalny i pamięć powinna zostać wydana pod koniec sposobu (Lub gdy garbage collector zdecyduje się to zrobić). Jednak aplikacja może pochłonąć ~ 224 MB do końca wszechświata.

Każda pomoc będzie świetna.

Odpowiedz

0

Czy konieczne jest renderowanie obrazu bitmapowego w tej samej rozdzielczości i pikselach? Możesz utworzyć zapisywalnyzmiennik przy znacznie niższym zestawie pikseli i wywołać metodę renderowania. Ponieważ writeablebitmap przenosi odwołanie do oryginalnych uielements podczas wywoływania renderowania, w tym przypadku będziesz miał 3 porcje: 1) oryginalne uielement, 2) piksele w writeablebitmap, 3) odwołanie do skopiowanego oryginału.

Miałem podobny problem z WriteableBitmap pod względem wycieków pamięci i naprawiłem go od sprawdzania ten link: http://www.wintellect.com/CS/blogs/jprosise/archive/2009/12/17/silverlight-s-big-image-problem-and-what-you-can-do-about-it.aspx

Jeśli utworzyć kolejną WriteableBitmap i skopiować piksele, a następnie dysponowania pierwszego WriteableBitmap powinieneś zobaczyć trochę wydania pamięci - przynajmniej zrobiłem to w moim scenariuszu.

Powiązane problemy