Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Xamarin iOS memory leaks everywhere

We've been using Xamarin iOS for the last 8 months and developed a non-trivial enterprise app with many screens, features, nested controls. We've done our own MVVM arch, cross platform BLL & DAL as "recommended". We share code between Android and even our BLL/DAL is used on our web product.

All is good except now in release phase of project we discover irreparable memory leaks everywhere in the Xamarin iOS-based app. We've followed all the "guidelines" to resolve this but the reality is that C# GC and Obj-C ARC appear to be incompatible garbage collection mechanisms in the current way they overlay each other in monotouch platform.

The reality we've found is that hard cycles between native objects and managed objects WILL occur and FREQUENTLY for any non-trivial app. It's extremely easy for this to happen anywhere you use lambdas or gesture recognizers for example. Add in the complexity of MVVM and it's almost a guarantee. Miss just one of these situations and entire graphs of objects will never get collected. These graphs will lure other objects in and grow like a cancer, eventually resulting in a prompt and merciless extermination by iOS.

Xamarin's answer is an uninterested deferral of the issue and an unrealistic expectation that "devs should avoid these situations". Careful consideration of this reveals this as an admission that Garbage Collection is essentially broken in Xamarin.

The realization for me now is that you don't really get "garbage collection" in Xamarin iOS in the traditional c# .NET sense. You need employ "garbage maintanence" patterns actually get the GC moving and doing its job, and even then it'll never be perfect - NON DETERMINISTIC.

My company has invested a fortune trying to stop our app from crashing and/or running out of memory. We've basically had to explicitly and recursively dispose every damn thing in sight and implement garbage maintanence patterns into the app, just to stop the crashes and have a viable product we can sell. Our customers are supportive and tolerant, but we know this cannot hold forever. We are hoping Xamarin have a dedicated team working on this issue and get it nailed once and for all. Doesn't look like it, unfortunately.

Question is, is our experience the exception or the rule for non-trivial enterprise-class apps written in Xamarin?

UPDATE

See answer for DisposeEx method and solution.

like image 601
Herman Schoenfeld Avatar asked Aug 27 '14 16:08

Herman Schoenfeld


1 Answers

I have shipped a non-trivial app written with Xamarin. Many others have as well.

"Garbage collection" isn't magic. If you create a reference that is attached to the root of your object graph and never detach it, it will not be collected. That's not only true of Xamarin, but of C# on .NET, Java, etc.

button.Click += (sender, e) => { ... } is an anti-pattern, because you don't have a reference to the lambda and you can never remove the event handler from the Click event. Similarly, you have to be careful that you understand what you're doing when you create references between managed and unmanaged objects.

As for "We've done our own MVVM arch", there are high profile MVVM libraries (MvvmCross, ReactiveUI, and MVVM Light Toolkit), all of which take reference/leak issues very seriously.

like image 108
anthony Avatar answered Oct 05 '22 19:10

anthony