Bug 13102 - ParentViewController, NavigationController, TabBarController properties create reference cycles
Summary: ParentViewController, NavigationController, TabBarController properties creat...
Status: RESOLVED FIXED
Alias: None
Product: iOS
Classification: Xamarin
Component: XI runtime ()
Version: 6.3.x
Hardware: PC Mac OS
: --- enhancement
Target Milestone: Untriaged
Assignee: Bugzilla
URL:
Depends on:
Blocks:
 
Reported: 2013-07-08 17:27 UTC by Brendan Zagaeski (Xamarin Team, assistant)
Modified: 2014-04-07 14:09 UTC (History)
6 users (show)

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


Attachments
Example project (6.17 KB, application/zip)
2013-07-08 17:27 UTC, Brendan Zagaeski (Xamarin Team, assistant)
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:
RESOLVED FIXED

Description Brendan Zagaeski (Xamarin Team, assistant) 2013-07-08 17:27:24 UTC
Created attachment 4287 [details]
Example project

Accessing "related view controllers" via properties like `ParentViewController`, `NavigationController`, and `TabBarController` from a child view controller creates a reference cycle. Clearing the reference from the parent to the child is one work-around. For example, one way to break the cycle for a UINavigationController is to set `ViewControllers` to an empty `UIViewController[] {}` array as soon as the navigation controller is no longer needed. This is not very user-friendly. Perhaps the runtime can be adjusted so that these parent-child pairs get garbage collected without user intervention?

Attached: simple example that demonstrates the problem. 
1. Run with "Project > Profile - Mono".
2. Press the "Press me" button a few times to open and dismiss the PopoverController.
3. "Take a Memory Snapshot" in HeapShot.
4. Search for UINavigationController instances in HeapShot. None of the NavigationControllers or child ViewControllers have been garbage collected.


Related forum post: http://forums.xamarin.com/discussion/4953/
Comment 1 BB 2013-08-31 14:49:19 UTC
This is my #1 problem with Xamarin, garbage collection problems like this. Here is another one I put on Stack Overflow:

http://stackoverflow.com/questions/18547121/how-to-implement-the-ios-delegate-data-source-pattern-in-c-sharp-xamarin


Also this thread:

http://forums.xamarin.com/discussion/4953/harmless-looking-line-that-causes-controller-to-not-garbage-collect

PLEASE fix this soon!
Comment 2 Anton 2013-10-14 06:52:00 UTC
PLEASE fix this soon!
Comment 3 Brendan Zagaeski (Xamarin Team, assistant) 2014-02-01 00:23:34 UTC
## Update

This same complication also arises when accessing a "related view" of a UIView via the `Superview` property.

In the end, I think this enhancement request is a near duplicate of bug #1939. See in particular:
https://bugzilla.xamarin.com/show_bug.cgi?id=1939#c3

The comment says: "Unfortunately we've determined that it's pretty much impossible for MonoTouch to resolve this scenario [automatically]." Instead, the developer must help the Xamarin.iOS runtime by explicitly calling `Dispose()` to break the strong reference cycle [1, 2].


> [1] http://docs.xamarin.com/guides/cross-platform/application_fundamentals/memory_perf_best_practices/#Strong_Reference_Cycles_in_iOS

> [2] http://docs.xamarin.com/guides/cross-platform/application_fundamentals/memory_perf_best_practices/#Dealing_with_Strong_Reference_Cycles



## Calling `Dispose()` in the example project

In the particular case of the example project, adding a `Dispose()` call in `MyUINavigationController.ViewDidDisappear()` stops the memory leak. The same approach can be used for the other "related view controller" properties and the `Superview` property.
Comment 4 Sebastien Pouliot 2014-04-07 14:09:39 UTC
This issue is resolved when using the New-Refcount (NRC) feature [1]. This is not a new feature [2] but it has totally revamped [3] in the last two months based on the bug reports, like this one.

With XI 7.2.1 this features works with both Boehm (default) and Sgen garbage collectors. NRC has also been enhanced and, right now, there are no known issues (bugs) against it.

While NRC is not the default option (in 7.2.1) we plan to make it so in the near future. Additional testing and feedback on the feature would be appreciated.

[1] http://docs.xamarin.com/guides/ios/advanced_topics/newrefcount/
[2] http://docs.xamarin.com/releases/ios/MonoTouch_5/MonoTouch_5.2/
[3] Newer versions of Xamarin Studio will remove the experimental tag on the feature when XI 7.2.1+ is used.