C# 向后导航不会释放内存

C# 向后导航不会释放内存,c#,memory-management,xamarin,xamarin.ios,C#,Memory Management,Xamarin,Xamarin.ios,在我的应用程序中,使用Xamarin Profiler,我注意到每当我将VC推到堆栈并向后导航时,内存分配都不是空闲的。如果我再次推同一个视图,它会增加更多内存 我创建了一个要测试的示例项目,我发现它也做了同样的事情 样本项目: 我有两个视图控制器,VC1和VC2。VC1是根视图控制器 每当我从VC1中推出VC2时,都会分配内存,但当我返回时,内存不是空闲的。如果我继续按VC2,它会增加更多内存。在VC2中,我通过设计器添加了3个标签 在AppDelegate中: namespace TestS

在我的应用程序中,使用Xamarin Profiler,我注意到每当我将VC推到堆栈并向后导航时,内存分配都不是空闲的。如果我再次推同一个视图,它会增加更多内存

我创建了一个要测试的示例项目,我发现它也做了同样的事情

样本项目:

我有两个视图控制器,VC1和VC2。VC1是根视图控制器

每当我从VC1中推出VC2时,都会分配内存,但当我返回时,内存不是空闲的。如果我继续按VC2,它会增加更多内存。在VC2中,我通过设计器添加了3个标签

在AppDelegate中:

namespace TestSample
{
    [Register("AppDelegate")]
    public class AppDelegate : UIApplicationDelegate
    {
        public override UIWindow Window
        {
            get;
            set;
        }

        public override bool FinishedLaunching(UIApplication application, NSDictionary launchOptions)
        {
            Window = new UIWindow(UIScreen.MainScreen.Bounds);
            var nav = new UINavigationController(new MyViewController());
            Window.RootViewController = nav;
            Window.MakeKeyAndVisible();

            return true;
        }
    }
}
VC1:

VC2:


Xamarin.iOS中的垃圾收集根本没有中断。(在任何系统上!)都有一个普遍的误解,即拥有GC意味着不再需要担心内存消耗和(强)引用

iOS位于参考计数世界的顶部,这需要进行某些测量。所有这些都记录在案;是的,很难理解所有的细微差别

也就是说:我尝试了您的示例,VC2按预期收集(调用了Finalizer和
Dispose()
)。此外,探查器(1.0.2-2)未显示任何泄漏

我创建了两个基于XIB的控制器,并在第一个控制器上添加了一个按钮,在第二个控制器上添加了三个标签。您不必删除或处理任何标签,也不必在您的案例中的第一个VC中取消订阅click事件


如果您的项目表现不同,您将在某处保留对VC2的引用。也许你可以提供完整的项目,然后我可以看一看。

Xamarin.iOS中的垃圾收集一点也没有中断。(在任何系统上!)都有一个普遍的误解,即拥有GC意味着不再需要担心内存消耗和(强)引用

iOS位于参考计数世界的顶部,这需要进行某些测量。所有这些都记录在案;是的,很难理解所有的细微差别

也就是说:我尝试了您的示例,VC2按预期收集(调用了Finalizer和
Dispose()
)。此外,探查器(1.0.2-2)未显示任何泄漏

我创建了两个基于XIB的控制器,并在第一个控制器上添加了一个按钮,在第二个控制器上添加了三个标签。您不必删除或处理任何标签,也不必在您的案例中的第一个VC中取消订阅click事件


如果您的项目表现不同,您将在某处保留对VC2的引用。也许你可以提供完整的项目,然后我可以看一看。

你可以发布你的VC2吗?这里有一个循环引用,需要通过将某物设置为null或调用
Dispose()
来切断关系,否则GC将永远看不到符合收集条件的对象。VC2只有3个标签,我通过设计器在XIB文件中添加了这些标签。编辑VC2@PLOW如果强制执行一个
GC.Collect()
it可以回收内存?@sushingover它不会回收内存。“在Xamarin中,垃圾回收基本上是被破坏的”。Xamarin将释放内存,但需要时间。看看这个问题,你能发布你的VC2吗?这里有一个循环引用,需要通过将某物设置为null或调用
Dispose()
来切断关系,否则GC将永远看不到符合收集条件的对象。VC2只有3个标签,我通过设计器在XIB文件中添加了这些标签。编辑VC2@PLOW如果强制执行一个
GC.Collect()
it可以回收内存?@sushingover它不会回收内存。“在Xamarin中,垃圾回收基本上是被破坏的”。Xamarin将释放内存,但需要时间。看看这个问题
namespace TestSample
{
    public partial class MyViewController : UIViewController
    {
        public MyViewController() : base("MyViewController", null)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            // Perform any additional setup after loading the view, typically from a nib.
        }
        public override void ViewWillAppear(bool animated)
        {
            base.ViewWillAppear(animated);

            btn1.TouchUpInside += Btn1_TouchUpInside;
        }

        void Btn1_TouchUpInside(object sender, EventArgs e)
        {
            NavigationController.PushViewController(new MyViewController2(), true);
        }

        public override void ViewDidDisappear(bool animated)
        {
            base.ViewDidDisappear(animated);
            btn1.TouchUpInside -= Btn1_TouchUpInside;
        }

        public override void DidReceiveMemoryWarning()
        {
            base.DidReceiveMemoryWarning();
            // Release any cached data, images, etc that aren't in use.
        }
    }
}
namespace TestSample
{
    public partial class MyViewController2 : UIViewController
    {
        public MyViewController2() : base("MyViewController2", null)
        {
        }

        public override void ViewDidLoad()
        {
            base.ViewDidLoad();
            // Perform any additional setup after loading the view, typically from a nib.
        }

        public override void DidReceiveMemoryWarning()
        {
            base.DidReceiveMemoryWarning();
            // Release any cached data, images, etc that aren't in use.
        }

        public override void ViewDidDisappear(bool animated)
        {
            base.ViewDidDisappear(animated);
            /*foreach (UIView view in View.Subviews) {
                view.RemoveFromSuperview();
            }*/

            label1.RemoveFromSuperview();
            label2.RemoveFromSuperview();
            label3.RemoveFromSuperview();

            label1.Dispose();
            label2.Dispose();
            label3.Dispose();
        }
    }
}