.net c#导航到页面时出现内存不足异常

Out Of Memory-exception when navigating to page
2020-10-22
  •  译文(汉语)
  •  原文(英语)

我正在制作一个简单的Windows Phone 8.1 Silverlight应用程序.我的想法是,我可以输入一个图片(用相机拍摄),然后在其中添加标题和描述文字.保存条目后,主页上会出现一个按钮以进行查看.因此,我输入了3个条目,并将它们列在主页上,但是导航到他们的页面几次后,我得到了一个N​​avigationFailed以及OutOfMemoryException.这些页面很简单,它们仅包含1张图片以及一些文本块.

我认为问题在于图像仍在内存中,这就是为什么我尝试将它们设置为null并强制垃圾收集器的原因,但这根本没有帮助.是什么原因导致OutOfMemory异常?

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        string id= "";
        if (NavigationContext.QueryString.TryGetValue("id", out id))
        {
            foreach (cEntry entry in helper.entries)
            { 
                if (entry.id.ToString() == id)
                {
                    textBlock_viewText.Text = entry.text;
                    textBlock_viewTitle.Text = entry.title;

                    using (IsolatedStorageFile userStore = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (userStore.FileExists(entry.imageFileName))
                        {
                            using (IsolatedStorageFileStream imgStream = userStore.OpenFile(entry.imageFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                            {
                                BitmapImage bmp = new BitmapImage();
                                bmp.SetSource(imgStream);
                                image_viewEntryImage.Source = bmp;
                                bmp = null;
                            }
                        }
                    }
                }
            }
        }
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
        image_viewEntryImage.Source = null;
        GC.Collect();
    }
解决过程1

您可能需要冻结BitmapImage.

如上所述这里有一个与WPF(Windows Phone的发展典型框架),其中BitmapImages可以被错误地保持活力的问题.虽然据说它已经修复了一段时间,但据报道人们在某些情况下仍然看到该问题.

速聊1:
MSDN说有...
速聊2:
当然可以,尽管他们不会给它一个稍微不同的名称或有助于区分它的名称似乎有些奇怪.无论如何,从您显示的结果看,似乎没有正确地垃圾回收BitmapImage.您可能想找到一个与Windows Phone一起使用的免费内存探查器,然后查看是否可以找出对它的引用.
解决过程2

而不是将bmp设置为null,请尝试此操作.

 public static void DisposeImage(BitmapImage image)
{
    Uri uri= new Uri("oneXone.png", UriKind.Relative);
    StreamResourceInfo sr=Application.GetResourceStream(uri);
    try
    {
        using (Stream stream=sr.Stream)
        {
            image.DecodePixelWidth=1; //This is essential!
            image.SetSource(stream);
        }
    }
    catch { }
}

调用此方法,然后将bmp设置为null,然后将source设置为此自定义方法.GC无法清除内存.详细信息在这里为什么列表框中有图像时为什么出现OutOfMemoryException?

I'm making a simple Windows Phone 8.1 Silverlight app. The idea is that I can make an entry with a picture (taken with the camera) and add a title and description text to it. Once an entry is saved, a button appears on the main page to view it. So I made 3 entries and they are listed on the main page, but after navigating to their pages a few times, I get a NavigationFailed along with OutOfMemoryException. The pages are simple, they only contain 1 image along with some textblocks.

I thought the issue is that the images are still in memory, that's why I try to set them to null and force the garbage collector, but that didn't help at all. What could cause the OutOfMemory-exception?

    protected override void OnNavigatedTo(NavigationEventArgs e)
    {
        base.OnNavigatedTo(e);

        string id= "";
        if (NavigationContext.QueryString.TryGetValue("id", out id))
        {
            foreach (cEntry entry in helper.entries)
            { 
                if (entry.id.ToString() == id)
                {
                    textBlock_viewText.Text = entry.text;
                    textBlock_viewTitle.Text = entry.title;

                    using (IsolatedStorageFile userStore = IsolatedStorageFile.GetUserStoreForApplication())
                    {
                        if (userStore.FileExists(entry.imageFileName))
                        {
                            using (IsolatedStorageFileStream imgStream = userStore.OpenFile(entry.imageFileName, System.IO.FileMode.Open, System.IO.FileAccess.Read))
                            {
                                BitmapImage bmp = new BitmapImage();
                                bmp.SetSource(imgStream);
                                image_viewEntryImage.Source = bmp;
                                bmp = null;
                            }
                        }
                    }
                }
            }
        }
    }

    protected override void OnNavigatedFrom(NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
        image_viewEntryImage.Source = null;
        GC.Collect();
    }
Solutions1

You may need to freeze the BitmapImage.

As described here there is an issue with WPF (the typical framework for Windows Phone development) where BitmapImages can be incorrectly kept alive. While it was supposedly fixed a while back, people have reported still seeing the problem in some cases.

Talk1:
MSDN says there is...
Talk2:
Certainly possible, though it seems a little odd that they wouldn't give it a slightly different name or something to help distinguish it. At any rate, from what you've shown it seems likely that BitmapImage isn't properly being garbage collected. You might want to find a free memory profiler that works with Windows Phone and see if you can figure out what's keeping a reference to it.
Solutions2

Instead of setting bmp as null try this.

 public static void DisposeImage(BitmapImage image)
{
    Uri uri= new Uri("oneXone.png", UriKind.Relative);
    StreamResourceInfo sr=Application.GetResourceStream(uri);
    try
    {
        using (Stream stream=sr.Stream)
        {
            image.DecodePixelWidth=1; //This is essential!
            image.SetSource(stream);
        }
    }
    catch { }
}

call this method and set source as this custom method after that assing bmp as null. The GC not able to clear the memory. details are here Why do I get an OutOfMemoryException when I have images in my ListBox?

转载于:https://stackoverflow.com/questions/30576763/out-of-memory-exception-when-navigating-to-page

本人是.net程序员,因为英语不行,使用工具翻译,希望对有需要的人有所帮助
如果本文质量不好,还请谅解,毕竟这些操作还是比较费时的,英语较好的可以看原文

留言回复
我们只提供高质量资源,素材,源码,坚持 下了就能用 原则,让客户花了钱觉得值
上班时间 : 周一至周五9:00-17:30 期待您的加入