我们可以强制使用 Dart 垃圾收集器吗?

Can we force the Dart Garbage Collector?

我正在尝试为 Streams 模拟内存泄漏(出于教育目的),但如果 GC 尚未 运行,我无法确定内存是否确实泄漏。

我可以在纯 Dart 测试中强制执行 GC 扫描吗?

您可以从 Dart DevTools Web GUI 进行操作。 https://dart.dev/tools/dart-devtools

更新了使用 vm_service 包的示例

对于较新的 Dart 版本,我们可以使用 dart:developer API 与 Dart VM 进行通信。这也是新 Dart DevTools 从 VM 获取数据并执行触发垃圾收集器等操作的方式,您仍然可以通过进入 Web 界面手动执行这些操作。

如果你想从代码本身触发它,你可以使用 vm_service 包来实现,这使得与 Dart VM 服务协议的 API 交互变得容易。

可以在这里看到一个例子:

import 'dart:developer';
import 'dart:isolate';
import 'package:vm_service/vm_service_io.dart';

Future<void> main(List<String> args) async {
  final serverUri = (await Service.getInfo()).serverUri;

  if (serverUri == null) {
    print('Please run the application with the --observe parameter!');
    return;
  }

  final isolateId = Service.getIsolateID(Isolate.current)!;
  final vmService = await vmServiceConnectUri(_toWebSocket(serverUri));
  final profile = await vmService.getAllocationProfile(isolateId, gc: true);
  
  print(profile.memoryUsage?.heapUsage);
}

List<String> _cleanupPathSegments(Uri uri) {
  final pathSegments = <String>[];
  if (uri.pathSegments.isNotEmpty) {
    pathSegments.addAll(uri.pathSegments.where(
      (s) => s.isNotEmpty,
    ));
  }
  return pathSegments;
}

String _toWebSocket(Uri uri) {
  final pathSegments = _cleanupPathSegments(uri);
  pathSegments.add('ws');
  return uri.replace(scheme: 'ws', pathSegments: pathSegments).toString();
}

getAllocationProfile 方法采用可选参数 gc,记录为:

If gc is provided and is set to true, a garbage collection will be attempted before collecting allocation information. There is no guarantee that a garbage collection will be actually be performed.

所以这真的是你能做的最好的了。此外,此解决方案仅在使用 --observe 参数启动程序时才有效。所以除了调试目的之外,你不应该使用它。