【问题标题】:Listbox with a lot of items and images use too much memory包含大量项目和图像的列表框占用过多内存
【发布时间】:2012-07-27 11:55:35
【问题描述】:

我有一个枢轴视图,有 6 个枢轴项。每个数据透视项都包含一个电影列表。每部电影都有一个封面图片,旁边还有一个标题和一些其他元数据。显然,要按照我的意愿设置样式,必须使用一些网格/堆栈面板。另外,我有每个项目的上下文菜单。在我的列表框上方,我有一个性能进度条,可以在加载数据时显示(我从 Web API 获取所有内容)。我的问题是其中一个列表包含的电影比其他列表多得多,大约 100 部。加载此列表时,应用程序使用大约 150-160 mb 内存,超过了 90 mb 的限制。看起来所有图像和内容都已立即加载(我认为这会导致此问题)。

我想要的是这样的:

首先加载标题和元数据,然后仅加载列表中用户当前所在位置的图像,以便在用户向下滚动之前加载列表中较长的图像。

我尝试过使用 deferredloadlist、lazylist 和普通列表框,并尝试将虚拟化设置为标准和回收,但没有结果。我必须承认我不确定所有这些事情到底是做什么的。有谁知道我该如何解决这个问题?提前致谢。

附言。列表框的 xaml 代码有些笨拙,所以我决定不在这篇文章中包含它。如果您真的需要查看它以提供帮助,请告诉我。

更新:我已经能够通过使用虚拟化列表框来减少内存使用量,但它仍然在 100 mb 左右。我在某处读到设置 bitmapImage.ImageSource =null;完成使用图像后,会将其从内存中清除。当它们在列表框中时,我如何为每个图像执行此操作?

【问题讨论】:

  • 请在 pastebin.com 中分享您的 xaml 代码,以便我可以重现并建议一个干净的解决方案

标签: c# windows-phone-7 memory listbox virtualization


【解决方案1】:

ListBox 本身并不占用太多内存。这是 ListBoxItems 的内容。虚拟化面板仅创建可见的 ListBoxItems(加上更多)并破坏屏幕外的 ListBoxItems。因此,请确保您的 ListBox 使用虚拟化面板,例如通过不设置 ListBox.ItemsPanel。

对于虚拟化,Panel 需要有一个受限制的大小 - 否则它将创建所有 ListBoxItems。通常,这是通过将 ListBox 放入 Grid 或通过设置 Width/Height 为 ListBox 提供一个受约束的大小来完成的。但是,如果您将 ListBox 放置在非约束容器(例如 ScrollViewer、StackPanel 等)中,则 ListBox 的大小是无限的,ItemsPanel 将随心所欲地增长,并且所有 ListBoxItems 都会被创建——即使它们'远离屏幕。

【讨论】:

  • 对不起,我整个周末都不在家。这看起来很有帮助。谢谢,我现在试试看。
  • 当我删除 -tag 时,上下文菜单似乎不起作用。但即便如此,并且列表框位于网格内,整个列表框也会立即加载
  • 在这种情况下,我建议您尽可能简化页面和DataTemplate。您根本不应该看到任何内存使用情况。然后重新激活 DataTemplate 的各个元素,直到您看到内存使用量显着增加。最后重新激活页面元素,直到看到内存使用量增加。
  • 在您的帮助下,通过减小我从服务器获得的图像大小,我能够将内存使用量减少到最大 75~ mb。我觉得我可以做更多的事情,但我会自己弄清楚。感谢大家的帮助!
【解决方案2】:

你尝试过延迟图片下载吗?:

public class ItemViewModel 
{
   private BitmapImage _image;
   public BitmapImage Image 
   {
      get{

      if(_image == null)
      {
         _image = new BitmapImage();
          StartDownloadImageAsync();
      }
       return _image;
      }
   }
}

下载图像后 - 将其设置为 _image 并调用 RaisePropertyChanged("Image"); 因此,在虚拟化列表框上,您将只下载可见项目的图像。

如果你这样做了,你可以尝试对列表进行分页。

【讨论】:

  • 感谢您的回复。我没试过,现在试试。我想我忘了提到,即使没有图像,内存消耗也很重。有什么想法我还能做些什么来降低它?
  • 您应该简化您的 xaml。删除所有未使用的 DataTemplates 和样式,尝试使用 StackPannel 而不是 Grid 并注意内存泄漏(如果您订阅某些事件,请不要忘记取消订阅等)
  • 你的图片有多大?如果您的网络服务允许,您可以尝试下载缩略图而不是全尺寸图片。
  • 图片没有那么大,所以我认为这不是问题。
  • 看看Memory Profiler (windowsteamblog.com/windows_phone/b/wpdev/archive/2012/02/01/…),会不会有别的问题?
猜你喜欢
  • 1970-01-01
  • 2017-03-15
  • 2010-12-26
  • 2012-06-20
  • 1970-01-01
  • 1970-01-01
  • 2013-01-05
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多