WP8 Memory leak opening and closing PhoneApplicationPage

假如想象 提交于 2019-12-23 16:41:53

问题


I'm creating a Windows phone application that shows a list of thumbnails. I'm using a LongListSelector to do it.

My application has memory leaks when I navigate forward and backward to the thumbnails list some times. I review the memory usage while using the App and I see that the memory increases when opening the page with the thumbnails (as I expect to). When I navigate back to the previous page the memory usage decrease but not as much at it was increased. Repeating the proces several times it ends in an out of memory exception.

I created a test application that only has two pages. One with a button to navigate to other that loads a set of potos in a LongListSelector. I create this App to be sure that the memory leak is not caused by something else.

In this simple test the memory usage behaves as it does in my App.

Here is the main code of my page with the 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);
}

And here is the code of the button on the other page:

private void Button_Click_1(object sender, RoutedEventArgs e)
{
    NavigationService.Navigate(new Uri("/Page1.xaml", UriKind.RelativeOrAbsolute));

}

回答1:


LongListSelector is a known source of leaks. Those leaks become especially troublesome when you're using controls like Image, which uses a large amount of memory.

The best solution, so far, is to avoid LongListSelector altogether. But it you can't find a suitable alternative, you have a few workarounds:

  • In Page1, in the OnNavigatedFrom event, force the liberation of the pictures. There's a few ways to do that, but usually setting the ImageSource property to null is enough

  • Make a custom control to do the dirty work for you

The custom control could look like:

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;
        }
    }
}

Then, just wrap all your pictures in that control:

<my:SafePicture>
    <Image Source="{Binding Path=Thumbnail}" />
</my:SafePicture>

And that should do the trick. Note that you will still be leaking memory, but in far more reasonable amounts.



来源:https://stackoverflow.com/questions/17492839/wp8-memory-leak-opening-and-closing-phoneapplicationpage

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!