UWP: Как удалить изображение из памяти? - PullRequest
1 голос
/ 30 октября 2019

Как удалить предыдущее изображение из памяти?

Способ установки изображения в сетке изображений:

public async Task Show(KeyValuePair<Image, Storyboard> imageStoryboard)
{
    if (isVisible)
    {
        return;
    }
    isVisible = true;
    this.ImageComponent = imageStoryboard.Key;

    // элемент показан сохраняем его страницу
    Models.Page.Save(ImageData.Page, ImageData.NextPageLink);

    BitmapImage _bitmapImage = await GetBitmapImage(ImageData.ThumbnailUrl);

    // если высота неопределена вычисляем её
    if (Height == 0)
    {
        PixelHeight = _bitmapImage.PixelHeight;
        PixelWidth = _bitmapImage.PixelWidth;
        CalcHeight();
    }

    // параметры изображения
    ImageComponent.Width = App.Settings.side_size;
    ImageComponent.Height = Height - MARGIN;
    ImageComponent.Margin = new Thickness(0, MarginTop, 0, 0);
    Grid.SetColumn(ImageComponent, Column);
    ImageComponent.DataContext = ImageData;
    ImageComponent.Source = _bitmapImage;

    // анимация
    imageStoryboard.Value.Stop();
    imageStoryboard.Value.Begin();
}

Я установил новый источник ImageComponent.Source = _bitmapImage;, но как удалить предыдущее изображение из памяти? Когда я загружаю все больше и больше изображений, память теряется и приложение закрывается. И когда я загружаю предыдущие изображения, они загружаются так быстро.

Этот метод для загрузки изображения: https://pastebin.com/AWHpNCJU

1 Ответ

1 голос
/ 30 октября 2019

Вы не можете напрямую манипулировать памятью, приложение будет периодически вызывать утилиту очистки мусора GC.Collect для очистки неиспользуемых ресурсов. Но эта очистка предполагает, что на текущий объект больше нет ссылок. Поэтому, пожалуйста, проверьте, не были ли ваши ресурсы изображений выпущены вовремя.

Вот документ о Сборке мусора и производительности .

Вы можете удалить файлы изображений с изображениякэшируйте, установив все связанные значения Image.Source в null.

Чтобы оптимизировать использование памяти, попробуйте использовать Uri в качестве источника изображения вместо Stream, который является содержимым документа:

Чтобы предотвратить декодирование изображений более одного раза, назначьте свойство источника изображения из универсального идентификатора ресурса (URI), а не используйте потоки памяти, когда это возможно. Платформа XAML может связывать один и тот же универсальный идентификатор ресурса (URI) в нескольких местах с одним декодированным изображением, но она не может делать то же самое для нескольких потоков памяти, даже если они содержат одни и те же данные.

Для этогонекоторые примеры приведены в документации :

// use this
var bitmapImage = new BitmapImage();
myImage.Source = bitmapImage;
bitmapImage.UriSource = new URI("ms-appx:///static/posts/cool-image.png", UriKind.RelativeOrAbsolute);
// not this
var bitmapImage = new BitmapImage();
bitmapImage.UriSource = new URI("ms-appx:///static/posts/cool-image.png", UriKind.RelativeOrAbsolute);
myImage.Source = bitmapImage;

Вы также упомянули, что при загрузке изображений память будет сильно увеличиваться. В связи с этим вы можете использовать DecodePixelWidth / DecodePixelHeight, чтобы уменьшить фактическое разрешение изображения.

Например, если вы получаете изображение 1080P, но размер элемента управления изображением составляет всего 100x100, если вы не измените пиксели изображения, это приведет к ненужной растрате ресурсов. DecodePixelWidth / DecodePixelHeight может использоваться для ограничения размера изображения, что может эффективно уменьшить использование памяти.

Для получения дополнительной информации о классе изображения и производительности см. Оптимизация ресурсов изображения .

Если вы пытаетесь описанными выше способами и все еще не можете эффективно уменьшить объем памяти, проверьте использование памяти с помощью средства отладки в Visual Studio и сделайте снимок для сравнения иувидеть, какие объекты были выпущены. Это документ о Использование окна памяти .

С уважением.

...