Flutter 上的内存泄漏监控

本文介绍了如何在Flutter中实现内存泄漏监控,通过Dart的弱引用和vm_service库,检测和定位内存泄漏。作者详细讲解了Dart的弱引用、vm_service的使用,以及在1.9.1版本Flutter框架上的内存泄漏问题和解决方法。
摘要由CSDN通过智能技术生成

一、前言

Flutter 所使用的 Dart 语言具有垃圾回收机制,有垃圾回收就避免不了会内存泄漏。在 Android 平台上有个内存泄漏检测工具 LeakCanary[1], 它可以方便地在 debug 环境下检测当前页面是否泄漏。本文将会带你实现一个 Flutter 可用的 LeakCanary,并讲述怎么用该工具检测出了 1.9.1 Framework 上的两个泄漏。

二、Dart 中的弱引用

在具有垃圾回收的语言中,弱引用是检测对象是否泄漏的一个好方式。我们只需弱引用观测对象,等待下次 Full GC, 如果 GC 之后对象为 null,说明被回收了, 如果不为 null 就可能是泄漏了。

Dart 语言中也有着弱引用,它叫 Expando<T> , 看下它的 API:

class Expando<T> {
  external T operator [](Object object "");
  external void operator []=(Object object, T value);
}

你可能会好奇上述代码弱引用体现在哪里呢?其实是在 expando[key]=value 这个赋值语句上。Expando 会以弱引用的方式持有 key,这里就是弱引用的地方。

那么问题来了,这个 Expando 弱引用持有的是 key, 但是本身又没有提供 getKey() 这样的 API, 我们就无从下手去得知 key 这个对象是否被回收了。

为了解决这个问题,我们来看下 Expando 的具体实现, 具体的代码在 expando_path.dart[2]

@path
class Expando<T> {
  // ...
  T operator [](Objet object "") {
    var mask = _size - 1;
    var idx = object._identityHashCode & mask;
    // sdk 是把 key 放到了一个 _data 数组内,这个 wp 是个 _WeakProperty
    var wp = _data[idx];

    // ... 省略部分代码
    return wp.value;
    // ... 省略部分代码
  }
}

注意: 此 patch 代码不适用于 Web 平台

我们可以发现这个 key 对象是放到了 _data 数组内, 用了一个 _WeakProperty 来包裹,那么这个 _WeakProperty 就是关键类了, 看下它实现,代码在 weak_property.dart[3]

@pragma("vm:entry-point")
class _WeakProperty {

  get key => _getKey();
  // ... 省略部分代码
  _getKey() native "WeakProperty_getKey";
  // ... 省略部分代码
}

这个类有我们想要的 key,可以用于判断对象是否还在。

怎么获取这种私有属性和变量呢?Flutter 中的 Dart 是不支持反射的(为了优化打包体积,关闭了反射), 有没有其他办法来获取到这种私有属性呢?

答案肯定是 “有”,为了解决上述问题, 我来向大家介绍一个 Dart 自带的服务——Dart VM Service

三、Dart vm_service

Dart VM Service[4] (后面简称 vm_service) 是 Dart 虚拟机内部提供的一套 Web 服务,数据传输协议是 JSON-RPC 2.0。不过我们并不需要要自己去实现数据请求解析, 官方已经写好了一个可用的 Dart SDK 给我们用:`vm_service`[5]

ObjRef, Objid 的作用

先介绍 vm_service 中的核心内容:ObjRefObjid

vm_service 返回的数据主要分为两大类,ObjRef(引用类型) 和 Obj(对象实例类型)。其中 Obj 完整的包含了 ObjRef 的数据, 并在其基础上增加了额外信息 (ObjRef 只包含了一些基本信息,例如࿱

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值