【问题标题】:Can we force the Dart Garbage Collector?我们可以强制 Dart 垃圾收集器吗?
【发布时间】:2020-09-03 19:09:10
【问题描述】:

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

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

【问题讨论】:

    标签: dart garbage-collection


    【解决方案1】:

    您可以从 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,该参数记录为:

    如果提供gc 并将其设置为true,则在收集分配信息之前将尝试进行垃圾收集。不能保证垃圾回收会真正执行。

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

    【讨论】:

    • 不太确定该功能的 API。
    • 这些链接都是 404 的
    • @shawnblais 是的,页面已被删除。我不知道原因,但它有点旧并且没有得到适当的维护。我可以看到大部分功能已经在 Dart DevTools 中实现,看起来相当不错:dart.dev/tools/dart-devtools
    • 啊,所以我猜再也无法从代码中调用它了?悲伤。
    • @shawnblais 好吧,之前从代码本身触发 GC 是不可能的。但现在是 Dart VM 服务协议。我今天添加了一个示例。
    猜你喜欢
    • 1970-01-01
    • 2017-05-07
    • 1970-01-01
    • 2015-02-12
    • 1970-01-01
    • 2013-08-10
    • 2011-05-14
    • 1970-01-01
    • 2010-09-16
    相关资源
    最近更新 更多