Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Huge memory usage in Xamarin

I have some problems running my app on some old Androiddevices, and I therefore downloaded a trail of Visual Studio Professionel, as it has Diagnostics Tools.

I tried doing some simple stuff in my app, and I find it is scaring, that Xamarin.Forms.BindableProperty+BindablePropertyContext takes a size (in bytes of course) of 2.196.088 in UWP, which you can see at the following screendump.

UWP Managed memory.

In the example I have justed navigated through 5 pages. On 2 of the pages there are ListViews, and one of them have been cleared 3 times, and filled with new data.

So do I have to call GC.Collect() after clearing the ListView?

like image 635
Lasse Madsen Avatar asked Nov 08 '22 00:11

Lasse Madsen


1 Answers

I've had a similar issue - navigating through pages a couple of times caused an OutOfMemoryException. For me the solution was to implement custom render for page with explicit Dispose() call.

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;
        }
    }
}

You can also take a look here but you need to be careful with disposing images, it may cause some problems if their parent page is in navigation stack and you want to go back.

like image 75
maddhew Avatar answered Nov 14 '22 21:11

maddhew