【问题标题】:Windows Phone Images Grid "Out of memory" errorWindows Phone 图像网格“内存不足”错误
【发布时间】:2014-11-12 23:05:53
【问题描述】:

当我尝试显示图像网格时,Windows Phone 上出现“内存不足”异常。 我玩了一点代码,认为Grid.Children.Add 给了我这个错误。

我已经创建了显示灰色矩形的自定义类,并且在加载图像后,它显示图像而不是该矩形。这里是:

   class ImageWIthLoader
   {
     private BitmapImage m_loader_bitmap;
     private BitmapImage m_source_bitmap;
     private Image m_image;

     public Image image
     {
         get { return m_image; }
     }

     //url - url to 120x120 image; width, height = 120 both
     public ImageWIthLoader(string url, int width, int height)
     {
         m_image = new Image();

         m_loader_bitmap = new BitmapImage(new Uri("Assets/Images/image_await_background.png", Uri Kind.Relative));
         m_loader_bitmap.DecodePixelWidth = width;
         m_loader_bitmap.DecodePixelHeight = height;

         m_image.Source = m_loader_bitmap;

         m_source_bitmap = new BitmapImage(new Uri(url));
         m_source_bitmap.CreateOptions = BitmapCreateOptions.None;
         m_source_bitmap.ImageOpened += bitmapLoaded;
     }

     private void bitmapLoaded(object sender, RoutedEventArgs e)
     {
         m_image.Source = m_source_bitmap;
         m_loader_bitmap.UriSource = null;
     }
   }

在另一个类中,我将这些图像添加到网格中(这是一系列图像,由先前解析的 json 中的 url 加载)

    private void addImageToGrid(ImageWIthLoader loader_image, int row, int col)
    {
        double margin = 0.05 * PIC_WIDTH;

        loader_image.image.SetValue(Grid.ColumnProperty, col);
        loader_image.image.SetValue(Grid.RowProperty, row);
        loader_image.image.Margin = new Thickness(margin);

        //comment out this string and everythins goes fine
        images_grid.Children.Add(loader_image.image);
    }

猜测一些 cmets:我已将 ImageWithLoader-s 保存到 List 以防止 GC 收集它们。 ImageWithLoader url 是一个 120x120 图片的 url,所以不能太重。

带有图像网格的页面的 XAML 的一部分:

       ....
        <ScrollViewer x:Name="scrollView" HorizontalAlignment="Left" Height="603" VerticalAlignment="Top" Width="456" >
            <Grid x:Name="images_grid" Height="596" Width="453"/>
        </ScrollViewer>
       ....

那么,请问,我做错了什么?我应该使用另一个控件而不是网格吗?还是我还缺少其他东西?

附:抱歉误导。尺寸 120x120 是显示的矩形,加载的图像尺寸为 800x800(例如),然后它们适合 120x120 的矩形。

附言如果我删除加载 m_loader_bitmap,则图片显示正常。 m_loader_bitmap 是 1px 灰色 png

【问题讨论】:

  • BitmapImage 存在已知的内存泄漏,您可以搜索 google 和 SO 寻找解决方法。
  • 除了 BitmapImage 之外还有其他类可以用来显示图像吗?我不会发布图像,我会在滚动到页面底部时让它们的数量不断增加。大约 100 张 120x120 的图片给了我内存不足异常

标签: c# xaml windows-phone-8 out-of-memory


【解决方案1】:

你好,把这段代码改成这样

public void ImageWIthLoader(string url, int width, int height)
 {
      Deployment.Current.Dispatcher.BeginInvoke(() =>
        {
     m_image = new Image();

     m_loader_bitmap = new BitmapImage(new Uri("Assets/Images/image_await_background.png", UriKind.Relative));
     m_loader_bitmap.DecodePixelWidth = width;
     m_loader_bitmap.DecodePixelHeight = height;

     m_image.Source = m_loader_bitmap;

     m_loader_bitmap = null;

     m_source_bitmap = new BitmapImage(new Uri(url));
     m_source_bitmap.CreateOptions = BitmapCreateOptions.None;
     m_source_bitmap.ImageOpened += bitmapLoaded;
        });
 }

或从这些链接中查找更多信息

Memory leak with BitmapImage

Memory consumption of BitmapImage/Image control in Windows Phone 8

WriteableBitmap Memory Leak

System.OutOfMemoryException

【讨论】:

  • 不。它没有用。仍然有崩溃。内存分析器显示大约 10 张图像占用超过 150 MB 的内存。怎么会?顺便说一句,抱歉误导。单个下载图像的大小为 800x800,然后此图像适合 120x120 矩形。
  • 我在某处读到过,Windows Phone 为每个应用程序提供最大 150 MB 的空间来运行,之后它将被系统自动关闭。如果您只想以 120 X 120 显示,则只需更改此行 m_loader_bitmap.DecodePixelWidth = 200; m_loader_bitmap.DecodePixelHeight = 200;
  • 我不明白我需要将这两行更改为什么?或者我需要使用更大的矩形? - 200x200 而不是 120x120?
  • 不,您需要将图像高度和宽度从 800 更改为 200,因为您仅在 120 X 120 矩形中显示图像,因此请减小图像大小
猜你喜欢
  • 2011-12-05
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多