Bug 32206 - ContextActions cause memory leak: Page is never destroyed
Summary: ContextActions cause memory leak: Page is never destroyed
Status: VERIFIED FIXED
Alias: None
Product: Forms
Classification: Xamarin
Component: iOS (show other bugs)
Version: 2.3.2
Hardware: Macintosh Mac OS
: Normal normal
Target Milestone: ---
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2015-07-21 11:13 UTC by Falko Schindler
Modified: 2017-07-14 07:10 UTC (History)
8 users (show)

Tags: ac
Is this bug a regression?: ---
Last known good build:


Attachments
Demo project (71.89 KB, application/zip)
2016-11-18 12:43 UTC, René
Details


Notice (2018-05-24): bugzilla.xamarin.com is now in read-only mode.

Please join us on Visual Studio Developer Community and in the Xamarin and Mono organizations on GitHub to continue tracking issues. Bugzilla will remain available for reference in read-only mode. We will continue to work on open Bugzilla bugs, copy them to the new locations as needed for follow-up, and add the new items under Related Links.

Our sincere thanks to everyone who has contributed on this bug tracker over the years. Thanks also for your understanding as we make these adjustments and improvements for the future.


Please create a new report on Developer Community or GitHub with your current version information, steps to reproduce, and relevant error messages or log files if you are hitting an issue that looks similar to this resolved bug and you do not yet see a matching new report.

Related Links:
Status:
VERIFIED FIXED

Description Falko Schindler 2015-07-21 11:13:41 UTC
Creating a ListView with its DataTemplate containing ContextActions seems to hold the ContentPage on iOS even after navigating back.

The following code implements a minimum example: A buttons pushes a new ListPage holding a ListView with three items. Each of them has a ContextAction assign within the cell constructor. A static counter shows the number of ListPage instances during construction and destruction. As can be seen from the Application Output, the number of instances grows when navigating back and forth between MainPage and ListPage.

public App()
{
    MainPage = new NavigationPage(new ContentPage {
        Content = new Button {
            Text = "Push",
            Command = new Command(o => MainPage.Navigation.PushAsync(new ListPage())),
        },
    });
}

class ListPage: ContentPage
{
    static int counter;

    public ListPage()
    {
        GC.Collect();
        Console.WriteLine("Page: " + ++counter);
        Content = new ListView {
            ItemsSource = new List<string>{ "Apple", "Banana", "Cherry" },
            ItemTemplate = new DataTemplate(typeof(MyCell)),
        };
    }

    ~ListPage()
    {
        Console.WriteLine("Page: " + --counter);
    }
}

class MyCell: ViewCell
{
    public MyCell()
    {
        View = new Label();
        View.SetBinding(Label.TextProperty, ".");
        ContextActions.Add(new MenuItem { Text = "Delete" });
    }
}

Note that, when removing the ContextActions.Add(...) line or moving it into OnAppearing (with corresponding ContextActions.Clear() in OnDisappearing) the number of instances does *not* grow. Furthermore, the example works just fine on Android.
Comment 1 Falko Schindler 2015-07-21 11:17:04 UTC
Please note, that moving the context actions into OnAppearing is no sufficient workaround. iOS won't render them due to another(?) bug: https://bugzilla.xamarin.com/show_bug.cgi?id=32201
Comment 2 Paul DiPietro [MSFT] 2015-08-24 22:25:15 UTC
Seeing the reproduction using the code you provided using the latest Forms (1.4.4.6392) and considering the acknowledgement of the other issue it's probably safe to set this to confirmed.
Comment 3 adrianknight89 2016-11-13 01:59:21 UTC
See https://github.com/xamarin/Xamarin.Forms/pull/524
Comment 4 René 2016-11-18 12:43:17 UTC
This is still a problem with Forms 2.3.2.127 and also 2.3.3.166pre4. I had a customer contact me about memory leaks in his app and it turns out he hits exactly this bug. I attached another very simple test case (XAML based). It is enough to add a ContextAction without any event handlers or Command and the ContentPage will not be collected.

Instructions:
Run example app on iOS Simulator, put a breakpoint into PageWithObservableCollection's Finalizer. Navigate forth and back in the app; the finaliser will never be called even if a GC is forced.
Now change PageWithObservableCollection.xaml and remove the context actions. Repeat steps above and the finaliser will be called when navigating back.


Android is not affected by this bug.
Comment 5 René 2016-11-18 12:43:49 UTC
Created attachment 18531 [details]
Demo project
Comment 6 Rui Marinho 2017-01-26 14:30:50 UTC
Should be fixed in 2.3.5-pre1
Comment 7 Saurabh Paunikar 2017-07-14 07:10:29 UTC
Verified on xamarin.form version 2.3.5-pre6

ScreenCast link: https://www.screencast.com/t/T9sgwNUE