Как избавиться от записываемого растрового изображения? (WPF)

Некоторое время назад я опубликовал вопрос, связанный с утечкой памяти WriteableBitmap, и, хотя я получил замечательные советы, связанные с этой проблемой, я все еще думаю, что есть серьезная ошибка / (ошибка, сделанная мной) / (Путаница) / (еще кое-что) здесь.

Итак, вот моя проблема:

Предположим, у нас есть приложение WPF с изображением и кнопкой. Источник изображения - это действительно большое растровое изображение (3600 * 4800 пикселей), когда оно отображается во время выполнения, приложение потребляет ~ 90 МБ.

Теперь предположим, что я хочу создать экземпляр WriteableBitmap из источника изображения (действительно большого изображения), когда это происходит, приложения потребляют ~ 220 МБ.

Теперь наступает сложная часть, когда модификации изображения (через WriteableBitmap) заканчиваются, и все ссылки на WriteableBitmap (по крайней мере, те, о которых я знаю) уничтожаются (в конце метода или путем их установки. значение null) память, используемая writeableBitmap, должна быть освобождена, а потребление приложением должно вернуться к ~ 90 МБ. Проблема в том, что иногда он возвращается, иногда нет.

Вот пример кода:

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

Как видите, ссылка является локальной, и память должна быть освобождена в конце метода (или когда сборщик мусора решит это сделать). Однако приложение могло потреблять ~ 224 МБ до конца вселенной.

Любая помощь была бы замечательной.


person Mario    schedule 08.10.2009    source источник


Ответы (1)


Нужно ли рендерить растровое изображение с таким же разрешением и пикселями? Вы можете создать записываемое растровое изображение с гораздо меньшим набором пикселей и вызвать метод рендеринга. Поскольку записываемая битовая карта содержит ссылку на исходные элементы пользовательского интерфейса при вызове рендеринга, в этом случае у вас будет 3 фрагмента: 1) исходный элемент пользовательского интерфейса, 2) пиксели в записываемой битовой карте, 3) ссылка на скопированный оригинал.

У меня была аналогичная проблема с записываемой битовой картой с точки зрения утечки памяти, и я исправил ее, просмотрев эту ссылку: http://www.wintellect.com/CS/blogs/jprosise/archive/2009/12/17/silverlight-s-big-image-problem-and-what-you-can-do-about-it.aspx

Если вы создадите другое записываемое растровое изображение и скопируете пиксели, а затем избавитесь от первого записываемого растрового изображения, вы должны увидеть некоторое освобождение памяти - по крайней мере, в моем сценарии.

person nyxtom    schedule 11.03.2010