1

当 CreateOptions 是任何东西但 DelayCreation 并且放在可视树中(在 Image 或 ImageBrush 中)时,BitmapImage 会泄漏内存

我在带有 SDK 7.1 的模拟器和电话(HTC Titan)上看到了这个步骤:

  1. 打开新的 WP 项目
  2. 在 App.xaml.cs 中启动一个新的调度程序计时器,每秒打印一次内存使用情况 (DeviceStatus) 并执行 GC.Collect()。(考虑更新一个字节数组,其大小计算为略小于 (MemoryUsageLimit - CurrentMemoryUsage))
  3. 在 ContentPanel 中添加一个名为 ImagePanel 的 StackPanel
  4. 在 ContentPanel 中添加 2 个按钮(1 个用于使用代码创建和添加 10 个图像到 ImagePanel,1 个用于清除 ImagePanel 的子项)
  5. 查找高分辨率图像(以便轻松查看内存使用情况)并将其托管在本地 IIS 上
  6. 单击按钮 1 时,写入:

    Random rand = new Random();
    for(int i=0 ; i<10 ; i++)
    {
       //use 192.168.55.100 instead of localhost when running on the phone
       //to be able to see traffic in fiddler.Change localhost to machinename for the emulator
       var uri = "http://localhost/images/bigimage.jpg?tc=" + rand.Next(Int32.MaxValue);
       var bitmap = new BitmapImage 
                        {
                          UriSource = new Uri(uri, UriKind.RelativeOrAbsolute),
                          CreateOptions = BackgroundCreation //or None or DelayCreation
                        };
      ImagePanel.Children.Add(new Image { Source = bitmap });
    }
    
  7. 单击按钮 2 时,写入:

    ImagePanel.Children.Clear();
    GC.Collect();
    GC.WaitForPendingFinalizers();
    GC.Collect();
    

尝试使用 CreateOptions 的所有变体并观察内存的差异。继续添加和删除元素,看看您将使用哪个 CreateOption 获得 OutOfMemoryException。

有人可以验证吗?

4

1 回答 1

0

因为 BitmapImage 依赖于 GDI+,所以这不是预期的行为吗?(因此本质上是非托管代码?) IIRC 这不是 ImagePanel 泄漏,而是 BitmapImage 一次又一次地创建。

如果您将该值分配给同一个 BitmapImage 对象,则不会出现问题。您确实需要在绘图线程上执行此操作,否则 GDI 会很合适)就个人而言,每当我在 WP7 中处理图像时,我都会使用ImageTools而不是本机类。输出可以直接分配给图像控件,但可以异步加载,使用更少的内存并且操作要快得多

于 2012-04-23T14:13:28.500 回答