Xamarin内存分析器对象增长理解

时间:2015-10-10 21:52:47

标签: c# ios memory-management xamarin xamarin.ios

我有一个大型的Xamarin iOS应用程序遭受随机崩溃 - 我认为这是由于内存问题。在尝试解决问题之前,我试图确保我完全理解如何正确处理所有内容,因此我创建了一个带有UINavigationController和2个屏幕的非常简单的示例应用程序:

Storyboard Layout

我的想法是使用分析器检查我在使用后正确清除了所有内容,所以我:

  1. 使用探查器启动我的应用程序
  2. 一旦加载了所有内容,就创建了一个快照。 (奇怪的是,我必须在对象增长为0之前单击3次)
  3. 点击“显示下一个屏幕”按钮并拍摄快照4。
  4. 点击“返回”按钮,然后点击“快照5”。
  5. 我的目标是5取消4,以便我知道一切都正确处理。然而,实际上创造了另外369个对象,而不是对象增长是一个负面的数字:

    Xamarin Profiler results

    我在Screen2ViewController中创建了一个dispose方法,我认为它可以解决这个问题:

    public partial class Screen2ViewController : UIViewController
        {
            public override void ViewDidDisappear (bool animated)
            {
                base.ViewDidDisappear (animated);
    
                this.Dispose ();
            }
            public Screen2ViewController (IntPtr handle) : base (handle)
            {
            }
    
            partial void GoBackButton_TouchUpInside (NSObject sender)
            {
                this.NavigationController.PopViewController(true);
            }
    
            protected override void Dispose (bool disposing)
            {
                this.ReleaseDesignerOutlets ();
                this.View.Dispose ();
                base.Dispose (disposing);
            }
        }
    

    我是否误解了这样一个事实:通过打开然后关闭一个新屏幕我应该期望净对象增长为0?如果没有,那么我做错了什么才能不正确地释放所有东西?

    我应该手动拨打this.ReleaseDesignerOutlets()还是自动调用?我确实在它上面设置了一个断点,它似乎永远不会被调用,因此将它添加到我的Dispose方法中。

2 个答案:

答案 0 :(得分:2)

这是SO post的一个很好的介绍泄漏内存的地方。

一般来说,我们可以说每个视图都需要从超级视图中移除,处理和取消。每个参考都需要打破,因此不存在循环参考。而且,即使如此,这不是最佳做法,调用GC.Collect()有时真的很有帮助。

同样好的读物是:

答案 1 :(得分:1)

关键是要确定哪些对象在快照之间保持活动状态,你应该打开那个对象以了解正在发生的事情。

有许多惰性缓存和延迟初始化过程会触发一次,并会在应用程序的生命周期内保留对象。因此,第一步是确定保留哪些对象,然后确定保留它们的原因。