First_Strike
First_Strike

Reputation: 1089

Flutter - Will BLoC stream instances cause memory leak when a widget is closed?

There are some scenarios where screens with their respective BLoCs are frequently created and closed. So I'm somewhat concerned about memory safety of the Streams instances created in this process, because it doesn't seem they are disposed somewhere or whether they are GC-ed. This clearly depends on the specific implementation of DART libraries and flutter. So if you know about their behavior, please let me know.

These are some scenarios I have encountered.

  1. Multi-tab browser-like application.
  2. Navigation through screens. (But it's not that harmful.)
  3. showDialog() senarios when there are BLoCs inside the dialog. This is a far more common senario. There could be a lot of dialog popping up frequently in an app.

I wonder if it is necessary to override dispose() function and explicitly close all streams in BLoCProvider. It seems existing tutorials didn't mention it.

Upvotes: 9

Views: 5593

Answers (1)

Rémi Rousselet
Rémi Rousselet

Reputation: 276957

Streams will properly be cleaned as long as they aren't used anymore. The thing is, to simply removing the variable isn't enough to unsure it's unused. It could still run in background.

You need to call Sink.close() so that it stops the associated StreamController, to ensure resources can later be freed by the GC.

To do that, you have to use StatefulWidget.dispose method:

abstract class MyBloc {
  Sink foo;
  Sink bar;
}

class MyWiget extends StatefulWidget {
  @override
  _MyWigetState createState() => _MyWigetState();
}

class _MyWigetState extends State<MyWiget> {
  MyBloc bloc;

  @override
  void dispose() {
    bloc.bar.close();
    bloc.foo.close();
    super.dispose();
  }

  @override
  Widget build(BuildContext context) {
    // ...
  }
}

Upvotes: 10

Related Questions