列表框中有大量项和图像会占用过多的内存。

3
我有一个透视视图,其中包含6个PivotItems。每个PivotItem都包含一组电影列表。每部电影都有一张封面图片,旁边有标题和其他一些元数据。为了将其样式设置为我想要的样子,我必须使用一些网格/堆栈面板。此外,每个项目都有上下文菜单。在我的ListBox上方,我有一个性能进度条,以显示在加载数据时(我从Web API获取所有内容)的状态。我的问题是,其中一个列表包含比其他列表多得多的电影,约100部。加载此列表时,应用程序使用大约150-160 MB的内存,超过了90 MB的限制。看起来好像所有的图像和内容都会立即加载(我认为这是引起问题的原因)。
我的要求是这样的:
首先加载标题和元数据,然后仅在用户当前所在的列表位置加载图像,以便在用户向下滚动到它之前不会加载更多的图像。
我已经尝试过使用deferredloadlist、lazylist和normal listbox,并且已经尝试将virtualization设置为standard和recycling,但没有结果。虽然我必须承认我不确定所有这些东西都是做什么的。有人知道我该怎么解决这个问题吗?谢谢您的帮助。
PS. ListBox的XAML代码有点笨拙,所以我决定不在此帖中包含它。不过如果你真的需要查看它来帮助我,请告诉我。
更新:我已经使用虚拟化ListBox成功地减少了内存使用量,但它仍然约为100 MB。我在某个地方读到,当完成使用图像时,将bitmapImage.ImageSource=null;设置为null会从内存中清除它。当它们在ListBox中时,我该如何做到这一点?

请在pastebin.com上分享您的XAML代码,以便我可以重现并提供一个干净的解决方案。 - bragboy
2个回答

4
ListBox本身并不占用太多内存,而是其中的ListBoxItems的内容占用较多内存。虚拟化面板只会创建可见的ListBoxItems(加上一些额外的),并销毁屏幕外的ListBoxItems。因此,请确保您的ListBox使用虚拟化面板,例如通过不设置ListBox.ItemsPanel实现。
为了进行虚拟化,面板需要具有受限大小-否则它会创建所有ListBoxItems。通常,这是通过将ListBox放入网格中或通过设置宽度/高度来完成的。但是,如果您将ListBox放置在非约束性容器中(例如ScrollViewer、StackPanel等),则ListBox的大小是无限的,ItemsPanel将增长到它想要的大小,并且所有ListBoxItems都会被创建-即使它们远离屏幕。

抱歉,我整个周末都不在。这看起来可能会非常有帮助。谢谢,我现在会尝试一下。 - Hans Petter Naumann
当我删除<ListBoxItem>标签时,上下文菜单似乎无法工作。但即使如此,并且将列表框放在网格内,整个列表框也会立即加载。 - Hans Petter Naumann
在这种情况下,我建议您尽可能简化页面和DataTemplate。您不应该看到任何内存使用情况。然后逐个重新激活DataTemplate的元素,直到您看到明显的内存使用增加。最后重新激活页面的元素,直到您看到内存使用增加。 - HDW Production
我能够将内存使用减少到最多75MB,感谢你的帮助以及缩小从服务器获得的图像尺寸。我认为还有一些我可以做的事情,但我能够自己解决。感谢你的所有帮助! - Hans Petter Naumann

1
你尝试过懒加载图片下载吗?
public class ItemViewModel 
{
   private BitmapImage _image;
   public BitmapImage Image 
   {
      get{

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

当你下载一张图片后,将其设置为_image并调用RaisePropertyChanged("Image");因此,在虚拟化的列表框中,你只会为可见项下载图片。

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


谢谢您的回复。我还没有尝试过,现在正在尝试。不过我想我忘了提到,即使没有图像,内存消耗也很大。您有什么其他降低内存消耗的建议吗? - Hans Petter Naumann
你应该简化你的XAML。删除所有未使用的DataTemplates和样式,尝试使用StackPanel代替Grid,并注意内存泄漏(如果你订阅了某个事件,请不要忘记取消订阅等)。 - Anton Sizikov
你的图片有多大?如果你的网络服务允许,你可以尝试下载缩略图而不是完整尺寸的图片。 - Anton Sizikov
图片不是很大,所以我认为那不是问题。 - Hans Petter Naumann
看一下内存分析器(http://windowsteamblog.com/windows_phone/b/wpdev/archive/2012/02/01/memory-profiling-for-application-performance.aspx),也许还有其他问题? - Anton Sizikov

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接