Search code examples
iosfluttermemory-leaksdelegatesautomatic-ref-counting

Memory Cycles in Flutter


Hello guys I am an iOS Developer building a Flutter app and I was wondering if the concept of memory cycle (retain cycle exists here). "Strong reference cycles negatively impact your application's performance. They lead to memory leaks and unexpected behaviour that is often hard to debug". By replacing a strong reference with a weak reference, the relationship between the objects remains intact and the strong reference cycle is broken. So in flutter there is no concept about weak reference. So how can you solve this problem, or there is no need to do that? Below I will leave an example.

abstract class MainScreenDelegate {
  didTapButton();
}

class MainScreen implements MainScreenDelegate {
 AnotherClass anotherClass;

  @override
  void initState() {
    anotherClass = AnotherClass(this);
  }

  @override
  void didTapButton() { }
}

class AnotherClass {
 MainScreenDelegate delegate;
 AnotherClass(this.delegate);
}

So the MainScreen has a strong reference to the AnotherClass and the AnotherClass has strong reference to the MainScreen. So are there any problems regarding the memory management in flutter or this is just an iOS related problem regarding their ARC (Automatic Reference Counting)? A fix in iOS would be to mark the delegate as weak.


Solution

  • Dart uses a garbage collector. Apple's ARC does not use a garbage collector; objects are deallocated immediately and synchronously once they become unreferenced. That has some advantages (predictable, deterministic behavior) but some disadvantages (cycles created from mutual references).

    Since garbage collectors run asynchronously and somewhat infrequently to process many potentially dead objects, they typically can afford to do more expensive operations, such as detecting and handling memory cycles. (For example, they can mark all currently reachable objects and delete everything else, a process known as mark-and-sweep.)

    Additional reading about Dart's garbage collector:

    So usually you shouldn't need to worry about memory cycles in Dart. However, that doesn't mean that you can't "leak" memory. For example, if you register a callback on an object but never unregister it, as long as that callback remains registered (and therefore reachable), it will maintain a reference on the object and keep it alive.

    Dart 2.17 added a WeakReference class, and earlier versions had a notion of weak references in the form of Expando objects), but they are slightly limited in what types they can be used with. They aren't frequently used; the main motivation for WeakReference was for use with dart:ffi.