Preserving Singleton instances with 0 referene count.

Here’s what happens in your specific case:

How Your Singleton Works

Your AppDatabase uses a lazy singleton pattern:

static AppDatabase? _instance;
static AppDatabase get instance => _instance ??= AppDatabase.fromSetup(kFirebaseSetup);

The _instance static field holds the only reference to your singleton.

Dart’s Garbage Collection Behavior

Yes, Dart has garbage collection that will clean up instances with zero references, including singletons. Here’s what happens:

  1. Static fields are NOT GC roots by themselves - they don’t automatically keep objects alive
  2. If no code is actively referencing the singleton, the static field _instance becomes the only reference
  3. During garbage collection, if the Dart VM determines that no reachable code can access the singleton, it can be collected

Practical Implications

In your Flutter app, the AppDatabase singleton will typically survive because:

  1. Implicit references: Your app likely has ongoing operations (streams, listeners, cached queries) that hold references to the database
  2. Framework integration: Firebase/Firestore may maintain internal references
  3. Active usage: Most database singletons are frequently accessed throughout the app lifecycle

However, if you have periods where:

  • All database operations complete
  • All streams are closed
  • No widgets or services hold references
  • No pending futures reference the database

Then the singleton CAN be garbage collected.

How to Ensure Persistence

If you need to guarantee the singleton persists for the entire app lifecycle, you could:

  1. Hold a reference in your main app class:
class MyApp extends StatefulWidget {
  static late final AppDatabase _db = AppDatabase.instance; // Keeps it alive
  // ...
}
  1. Use a different singleton pattern that creates the instance immediately:
static final AppDatabase _instance = AppDatabase.fromSetup(kFirebaseSetup);
static AppDatabase get instance => _instance;

Conclusion

Your current implementation may be garbage collected if all references are removed, but in practice, this is unlikely in a typical Flutter app due to ongoing database operations and framework integrations. The lazy initialization is generally fine for most use cases.