GC.Collect() in my Xamarin Forms project

CharlinCharlin DOUniversity ✭✭

Hello,
I have a problem trying to implement GC.Collect() in my Xamarin Forms project

What i exactly did is:
1-Create a new file in my android project: android-environment.sh
2-Add MONO_GC_PARAMS=soft-heap-limit=128m,bridge-implementation=tarjan inside
3-Set the build Action of this file: Android environment

In my class in my Xamarin Form project,
protected override void OnDisappearing ()
{

            this.BindingContext = null;
            ImagesList = null;
            this.Content = null;
            base.OnDisappearing ();
            GC.Collect ();

}

I tested it using Xamarin Profiler and i cant see any change, just my memory allocated increase

Posts

  • NMackayNMackay GBInsider, University mod

    @Charlin

    I would suggest using a custom Navigation page (if your not using master detail) and when the page pops of the nav stack then do your cleanup. I noticed when I 1st started with Forms that doing cleanup in OnDisappearing didn't work, it's also a bad idea as popping the native email client etc will trigger OnDisappearing even if you page is in still on the navigation stack essentially disconnecting your page from the BindingContext.

    Custom Nav page

    using OrderFinder.Data.Services;
    using Xamarin.Forms;
    
    namespace OrderFinder.CustomPages
    {
        public class CustomNavigationPage : NavigationPage
        {
            public CustomNavigationPage(Page content)
                : base(content)
            {
                Init();
            }
    
            private void Init()
            {
                Popped += (object sender, NavigationEventArgs e) =>
                {
                    var navpage = e.Page as IPageLifetime;
                    if (navpage != null)
                    {
                        navpage.CleanupPage();
                    }
                    e.Page.BindingContext = null;
                };
            }
        }
    }
    

    in your app.cs

    MainPage = new CustomNavigationPage(new StartPage())
    

    In your page code behind (assuming your using XAML)

    namespace OrderFinder.View
    {
        [XamlCompilation(XamlCompilationOptions.Compile)]
        public partial class OrderDetailPage : CustomTabbedPage, IPageLifetime
        {
            public OrderDetailPage(OrderListItem ord)
            {
                InitializeComponent();
                ((OrderDetailViewModel)this.BindingContext).RefreshCommand.Execute(ord);
            }
    
            public void CleanupPage()
            {
                ((OrderDetailViewModel)BindingContext).Cleanup();
                SimpleIoc.Default.Unregister<OrderDetailViewModel>();
            }
    }
    

    Basically in cleanup, clear and page event handler, message listeners etc and call a cleanup method in your ViewModel, I use MVVM Light which has an ICleanup interface but you can implement your own base VM class, in there cancel any operations such as service data fetches

            public override void Cleanup()
            {
                if (_taskCancel != null)
                {
                    try
                    {
                        if (_taskCancel.Token.CanBeCanceled)
                            _taskCancel.Cancel();
                    }
                    finally
                    {
                        _taskCancel = null;
                    }
                }
    
            }
    

    I found this approach much more successful for memory management and pages are now cleaned up when you navigate away and the apps are pretty robust.

    Also some useful info here about garbage colelction
    https://developer.xamarin.com/guides/android/advanced_topics/garbage_collection/

Sign In or Register to comment.