C# Xamarin中的大量内存使用

C# Xamarin中的大量内存使用,c#,android,xamarin.android,xamarin.forms,C#,Android,Xamarin.android,Xamarin.forms,我在一些旧的Android设备上运行我的应用程序时遇到了一些问题,因此我下载了Visual Studio Professionel,因为它有诊断工具 我试着在我的应用程序中做一些简单的事情,我发现这很可怕,Xamarin.Forms.BindableProperty+BindablePropertyContext在UWP中的大小(当然是字节数)为2.196.088,你可以在下面的屏幕转储中看到 在这个例子中,我刚刚浏览了5页。其中两个页面上有列表视图,其中一个已被清除3次,并填充了新数据 因此

我在一些旧的
Android
设备上运行我的应用程序时遇到了一些问题,因此我下载了Visual Studio Professionel,因为它有
诊断工具

我试着在我的应用程序中做一些简单的事情,我发现这很可怕,
Xamarin.Forms.BindableProperty+BindablePropertyContext
在UWP中的大小(当然是字节数)为
2.196.088
,你可以在下面的屏幕转储中看到

在这个例子中,我刚刚浏览了5页。其中两个页面上有
列表视图
,其中一个已被清除3次,并填充了新数据


因此,在清除
列表视图之后,我是否必须调用
GC.Collect()

我也遇到过类似的问题-在页面中导航几次会导致OutOfMemoryException。对我来说,解决方案是使用显式Dispose()调用实现页面的自定义呈现

公共类CustomPageRenderer:PageRenderer
{
专用导航页面_导航页面;
受保护的覆盖无效OnElementChanged(ElementChangedEventArgs e)
{
基础。一个要素发生变化(e);
_navigationPage=GetNavigationPage(元素);
SubscribeToPopped(_navigationPage);
}
私有void subscribeTopop(导航页面导航页面)
{
如果(navigationPage==null)
{
返回;
}
navigationPage.Popped+=OnPagePopped;
}
受保护的覆盖无效处置(布尔处置)
{
Log.Info(“===========================================”);
基地。处置(处置);
}
已弹出页面上的私有void(对象发送方、NavigationEventArgs参数)
{
if(args.Page!=元素)
{
返回;
}
处置(真实);
_navigationPage.Popped-=打开页面弹出;
}
私有静态导航页面GetNavigationPage(元素)
{
if(元素==null)
{
返回null;
}
while(true)
{
if(element.Parent==null | | element.Parent.GetType()==typeof(NavigationPage))
{
返回元素。将父元素作为NavigationPage;
}
element=element.Parent;
}
}
}

您也可以查看一下,但在处理图像时需要小心,如果它们的父页面位于导航堆栈中,并且您想返回,则可能会导致一些问题。

不建议调用
GC.Collect()
,因为它可能会破坏代码中的其他内容
Clear()
for
ListView
不会在对象上调用
Dispose()
,这意味着
GC
在收集对象之前必须花时间确保这些对象没有被引用到其他任何地方。如果需要,您可以循环并
Dispose()
列表视图中的每个项目,这将确保您销毁它们。看看这里@Everyone
GC.Collect()
从不破坏任何其他东西,它只会使应用程序变慢,因为这是一项CPU密集型工作。@AkashKava True,抱歉。它会消耗性能,不会破坏正在运行的代码,但会大大降低速度。。就像一个乐透了的汉克斯麦德休。我刚刚将90-95%的事件转换为命令,我希望这会有所帮助。另外5-10%我从构造器转移到OnDisappearing中的OnAppearing和unassigning。我已经将所有图像转换为9-patches(在Android上)。我希望这需要一些时间。
public class CustomPageRenderer : PageRenderer
{
    private NavigationPage _navigationPage;

    protected override void OnElementChanged(ElementChangedEventArgs<Page> e)
    {
        base.OnElementChanged(e);
        _navigationPage = GetNavigationPage(Element);
        SubscribeToPopped(_navigationPage);
    }

    private void SubscribeToPopped(NavigationPage navigationPage)
    {
        if (navigationPage == null)
        {
            return;
        }

        navigationPage.Popped += OnPagePopped;
    }

    protected override void Dispose(bool disposing)
    {
        Log.Info("===========Dispose called===========");
        base.Dispose(disposing);
    }

    private void OnPagePopped(object sender, NavigationEventArgs args)
    {
        if (args.Page != Element)
        {
            return;
        }

        Dispose(true);
        _navigationPage.Popped -= OnPagePopped;
    }

    private static NavigationPage GetNavigationPage(Element element)
    {
        if (element == null)
        {
            return null;
        }

        while (true)
        {
            if (element.Parent == null || element.Parent.GetType() == typeof(NavigationPage))
            {
                return element.Parent as NavigationPage;
            }

            element = element.Parent;
        }
    }
}