我正在创建一个显示缩略图列表的Windows手机应用程序。我正在使用LongListSelector来完成它。
当我向前和向后导航到缩略图列表时,我的应用程序有内存泄漏。我在使用应用程序时查看了内存使用情况,我发现在使用缩略图打开页面时内存会增加(正如我所期望的那样)。当我导航回上一页时,内存使用量会减少但不会增加。多次重复处理,它以内存不足为例结束。
我创建了一个只有两页的测试应用程序。一个带有导航到其他的按钮,用于在LongListSelector中加载一组potos。我创建这个应用程序,以确保内存泄漏不是由其他东西引起的。
在这个简单的测试中,内存使用情况与我的应用程序一样。
以下是使用thumbnais的页面的主要代码:
public class testObject
{
public string Title { get; set; }
public BitmapImage Thumbnail { get; set; }
}
protected override void OnNavigatedTo(NavigationEventArgs e)
{
photosList = new List<testObject>();
for (int i = 0; i < 200; i++)
{
BitmapImage bi = new BitmapImage(new Uri("/images/"
+ i.ToString()+".jpg",
UriKind.RelativeOrAbsolute));
photosList.Add(new testObject { Title = i.ToString(),
Thumbnail = bi });
}
GridPictures.ItemsSource = photosList;
}
protected override void OnBackKeyPress(
System.ComponentModel.CancelEventArgs e)
{
foreach (testObject test in photosList)
{
test.Thumbnail.DecodePixelHeight = 1;
test.Thumbnail.DecodePixelWidth = 1;
test.Thumbnail = null;
}
photosList.Clear();
photosList = null;
base.OnBackKeyPress(e);
}
以下是另一页上按钮的代码:
private void Button_Click_1(object sender, RoutedEventArgs e)
{
NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));
}
答案 0 :(得分:3)
LongListSelector
是已知的泄漏源。当你使用像Image
这样使用大量内存的控件时,这些泄漏会变得特别麻烦。
到目前为止,最好的解决方案是完全避免使用LongListSelector。但是你找不到合适的替代方案,你有一些解决方法:
在Page1中,在OnNavigatedFrom
事件中,强制解放图片。有几种方法可以做到这一点,但通常将ImageSource
属性设置为null就足够了
制作自定义控件以便为您执行脏工作
自定义控件可能如下所示:
public class SafePicture : System.Windows.Controls.ContentControl
{
public SafePicture()
{
this.Unloaded += this.SafePictureUnloaded;
}
private void SafePictureUnloaded(object sender, System.Windows.RoutedEventArgs e)
{
var image = this.Content as System.Windows.Controls.Image;
if (image != null)
{
image.Source = null;
}
}
}
然后,只需将所有照片包裹在该控件中:
<my:SafePicture>
<Image Source="{Binding Path=Thumbnail}" />
</my:SafePicture>
这应该可以解决问题。请注意,您仍然会泄漏内存,但需要更合理的数量。