Search code examples
c#memory-leaksxamarin.iosxamarinlifecycle

UIViewController does not get disposed


I am noticing intermittent crashes on my large app written in Xamarin iOS 7.2.2. Instruments shows me that my app is grows in memory usage without really going down.

I have made sure to nullify all events in my UIViewControllers, and despite that, my UIViewControllers are not being disposed.

I know they are not being disposed because breakpoints on them never execute.

Exemplary Dispose method:

    protected override void Dispose(bool disposing) {
        _someViewController = null;
        _otherView = null;
        ReleaseDesignerOutlets();
        base.Dispose(disposing);
    }

I am not doing anything fancy in them, except nullifying references to other views and releasing designer outlets, yet it never gets called.

Why is Dispose not being called after my view controller is popped from the navigation controller?


Solution

  • The following pattern helped minimize memory leaks

    1. Do not keep UIViewController's & UIView's in memory, always create them as needed and explicitly dispose when not needed.
    2. Within a dispose method, dispose "owned" UIViewController & UIView's
    3. Within dispose method, manually remove from parent and dispose all subviews
    4. Within dispose method, nullify all references to controllers & views
    5. Within dispose method, nullify all events
    6. Use new Refcount feature and new GC (project options)
    7. If using Sqlite, do this on startup
    Mono.Data.Sqlite.SqliteConnection.SetConfig(Mono.Data.Sqlite.SQLiteConfig.Serialized);
    

    Even though these steps should not be necessary according to Xamarin & iOS documentation, without them my app would never release memory. Now it collects reasonably, which shows that Xamarin GC between complex object graphs spanning ObjC & mono runtime are not properly collected (likely due to cyclic references). Manually breaking the object references simplifies the object reference graph allowing GC to occur much quicker and more reliably than otherwise.

    Xamarin should really look into this, intermittent crashes & memory leaks occur for complex apps.