Flutter 借助DevTools检测内存泄漏

3,123 阅读1分钟

在 Flutter 2.2 版本中,DevTools 的内存管理视图迎来重大的更新,使得内存调试更加便捷。下面我将演示如何通过 DevTools 检测内存泄漏,更详细的信息请见 官方文档

检测内存泄漏

准备工作

  1. profile 模式运行 app 后打开 DevTools, 并切换到 Memory 选项卡,如下图所示。

微信截图_20210609170743.png

  1. 打开设置,勾选 Enable advanced memory settings 选项,此时页面将出现 GC 按钮,用于手动触发 GC,如下图所示。

微信截图_20210609171622.png

  1. 点击 Take Heap Snapshot 获取内存快照,如下图所示,绿框为获取到的内存快照。

微信截图_20210609173033.png

  1. 点击内存快照,并选择你项目的 package 名称,例如我项目名是 basic。如下图所示,此时在绿框将出现对应 package 当前快照存在的内存对象。通过这些对象,我们就能判断内存是否被正常回收了。

微信截图_20210609173607.png

检测

  1. 为了模拟内存泄漏,我将打开 TestPage 并在其中开启一个 Timer
  late Timer _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      print('timer is running...');
    });
  }

  // @override
  // void dispose() {
  //   super.dispose();
  //   _timer.cancel();
  // }

打开 TestPage 后点击获取内存快照,如下图所示,TestPage 已出现在列表中。

1623232271(1).png

  1. 退出 TestPage ,手动触发 GC ,再次获取快照,此时如我们所想的,由于 Timer 未手动调用 cancel() 方法, 已造成内存泄漏,TestPage 将不会被正常回收,依旧出现在列表里。如下图所示

微信截图_20210609180111.png

  1. 修复内存泄漏,恢复 _timer.cancel()
  late Timer _timer;

  @override
  void initState() {
    super.initState();
    _timer = Timer.periodic(Duration(seconds: 1), (timer) {
      print('timer is running...');
    });
  }

  @override
  void dispose() {
    super.dispose();
    _timer.cancel();
  }

再次执行以上步骤,将发现 TestPage 已消失在列表中,被正常回收。

微信截图_20210609181733.png