【问题标题】:UWP: How to remove image from memory?UWP:如何从内存中删除图像?
【发布时间】:2019-10-30 11:54:28
【问题描述】:

如何从内存中删除之前的图像?

在图像网格中设置图像的方法:

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

【问题讨论】:

    标签: c# memory uwp bitmapimage


    【解决方案1】:

    不能直接操作内存,应用程序会定期调用垃圾清理 GC.Collect 清理未使用的资源。但是这个清理有个前提是当前对象不再被引用。所以请检查您的图片资源是否没有及时释放。

    这是关于Garbage Collection and Performance的文档。

    您可以通过将所有关联的Image.Source 值设置为空来从图像缓存中删除图像文件。

    为了优化内存使用,尽量使用Uri作为图片的来源,而不是Stream,也就是文档的内容:

    为防止图像被多次解码,请从统一资源标识符 (URI) 分配图像源属性,而不是尽可能使用内存流。 XAML 框架可以将多个位置的同一个统一资源标识符 (URI) 与一个解码图像相关联,但它不能对多个内存流执行相同的操作,即使它们包含相同的数据。

    为此,documentation 中提供了一些示例:

    // 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可以用来限制图片的大小,可以有效的减少内存占用。

    有关 Image 类和性能的更多信息,请参阅Optimize image resources

    当您尝试以上方法仍不能有效减少内存时,请通过Visual Studio的调试工具检查内存使用情况,并抓拍快照对比看看哪些对象被释放了。这是一篇关于Use the Memory windows的文档。

    最好的问候。

    【讨论】:

      猜你喜欢
      • 2015-11-21
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2017-08-13
      • 2013-01-14
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多