【问题标题】:WP7 memory leak? - Navigating between pages containing pivot items with listbox databindingWP7内存泄漏? - 在包含带有列表框数据绑定的数据透视项目的页面之间导航
【发布时间】:2011-01-28 18:03:22
【问题描述】:

我有一个主页,其中有 3 个枢轴项目,每个项目都有一个很重的 ListBox(每个大约 15Mb,这正常吗?)。 当某些操作发生时,我会在另一个页面中导航,那里有另一个带有 3 个项目的 Pivot 控件。到目前为止,一切都很好。 当我导航回主页时,我可以看到已用内存 +2 到 +4mb 的差异。每次我导航到新页面然后返回主页时,总使用内存都会增加 2-4 mb。我很确定我的代码没有任何问题。即使我的代码中存在内存泄漏,它也不会那么大。这可能与一些未发布的 UI 元素有关?我在两个页面中手动调用垃圾收集器 onNavigatedFrom 和 onNavigatedTo 以防万一,但仍然相同..

这可能是某些控件中的内存泄漏吗?正如我告诉你的,这两个页面都包含带有数据绑定列表框的数据透视项,并且数据在运行时不会更改。

谢谢

【问题讨论】:

  • 您是否为页面中的任何事件添加事件处理程序?未能停止监听这些事件是内存泄漏的常见原因。
  • 我在两个页面上都有几个事件处理程序,但我认为这些在页面被销毁时会被销毁。还是不行?
  • 你是对的,德里克。我有一个来自 dll 的控件,它可以建立网络连接。每次我离开页面时,该控件都不会被破坏(我可以看到 webexception)。如果我再次访问该页面,则会创建另一个控件。因此,十次访问后,我可以看到 10 个网络异常。这很奇怪。那么为了销毁这些对象我必须做什么呢?这个控件可能有一个计时器,每 1 分钟调用一次网址。
  • @Derek - 这并不完全正确,这取决于您要添加事件处理程序的对象的生命周期。例如,您不必删除从页面内的 UI 控件发出的事件的处理程序,例如 Button.Click。这是因为 Button 与页面具有相同的生命周期。

标签: xaml silverlight windows-phone-7


【解决方案1】:

如果您在页面上使用的任何控件有泄漏,那么这将导致页面的整个元素树泄漏(因为每个子级都保留对其父级的引用,反之亦然)。

即使您的代码是干净的,如果您使用来自有泄漏的外部方的控件,您的页面也可能泄漏。在这种情况下,您可以通过在 OnNavigatingFrom() 中从树中删除有问题的元素来减轻影响。这样只会泄露该控件,而不是整个页面。

广告控件目前属于该类别。以下是这方面的指导: http://msdn.microsoft.com/en-us/library/gg491975(v=msads.10).aspx

SL Toolkit 中的 ContextMenu 的类似故事,以防您正在使用它。

【讨论】:

    【解决方案2】:

    http://forums.create.msdn.com/forums/p/76007/466968.aspx 的讨论对我的应用非常有帮助。

    我做过和工作的事情(来自上面的链接):

    • 为所有页面声明析构函数(仅限 DEBUG)
    #if DEBUG
            ~MyPageView()
            {
                System.Windows.Deployment.Current.Dispatcher.BeginInvoke(new System.Action(() =>
                {
                    System.Windows.MessageBox.Show("MyPageView Destructing");
                    // Seeing this message box assures that this page is being cleaned up
                }));
            }
    #endif
    
    • 在 CompleteInitializePhoneApplication 方法中将以下内容添加到 App.xaml
            private void CompleteInitializePhoneApplication(object sender, NavigationEventArgs e)
            {
    #if DEBUG
                System.GC.Collect();
                System.GC.WaitForPendingFinalizers();
    #endif
                // Other usual stuff in this method
            }
    
    • 在离开页面时清除所有 DataContext
    protected override void OnNavigatedFrom(System.Windows.Navigation.NavigationEventArgs e)
    {
        base.OnNavigatedFrom(e);
    
        // Clear the page datacontext
        this.DataContext = null;
        // Clear any other datacontexts esp if the life time of the databound objects are different.
        MyDownloadProgressBar.DataContext = null;
        // Make sure that if there are any references to elements scoped to this page's lifetime are being held by any other global objects, then they should be cleared here
    }
    

    随着我在我的应用中找到更多管理内存的方法/技巧,我会不断更新这个答案。

    【讨论】:

    • 还没有更新。我已经有一段时间没有开发 WP 应用了。
    【解决方案3】:

    对不起,我的英语很糟糕。反正。我有同样的问题。我是这样解决的。

    protected override void OnBackKeyPress(System.ComponentModel.CancelEventArgs e)
        {
            base.OnBackKeyPress(e);
            timer.Tick -= timer_Tick;
            this.Loaded -= new RoutedEventHandler(timer_Tick);
            AnaMenu.cli.GetAboutCompleted -= client_GetAboutCompleted;
        }
    

    我将-= 用于事件。并修复它

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2019-12-18
      • 1970-01-01
      • 2016-06-07
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多