forceGC function

Future<void> forceGC({
  1. Duration? timeout,
  2. int fullGcCycles = 1,
})

Forces garbage collection by aggressive memory allocation.

Verifies that garbage collection happened using reachabilityBarrier. Does not work in web and in release mode.

Use timeout to limit waiting time. Use fullGcCycles to force multiple garbage collections.

The method is helpful for testing in combination with WeakReference to ensure an object is not held by another object from garbage collection.

For code example see https://github.com/dart-lang/leak_tracker/blob/main/doc/leak_tracking/TROUBLESHOOT.md

Implementation

Future<void> forceGC({
  Duration? timeout,
  int fullGcCycles = 1,
}) async {
  final stopwatch = timeout == null ? null : (Stopwatch()..start());
  final barrier = reachabilityBarrier;

  final storage = <List<int>>[];

  void allocateMemory() {
    storage.add(List.generate(30000, (n) => n));
    if (storage.length > 100) {
      storage.removeAt(0);
    }
  }

  while (reachabilityBarrier < barrier + fullGcCycles) {
    if ((stopwatch?.elapsed ?? Duration.zero) > (timeout ?? Duration.zero)) {
      throw TimeoutException('forceGC timed out', timeout);
    }
    await Future<void>.delayed(Duration.zero);
    allocateMemory();
  }
}