Flutter App 内存测试

Flutter 应用内存测试数据。

内存测试一 - 简单 UI

分别使用 Android 和 Flutter 实现最简单的界面

  • 显示一个文本
  • 显示一个图片

使用 TextView 显示 “Hello World!” 的 Android Demo,布局如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<?xml version="1.0" encoding="utf-8"?>
<androidx.constraintlayout.widget.ConstraintLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:app="http://schemas.android.com/apk/res-auto"
xmlns:tools="http://schemas.android.com/tools"
android:layout_width="match_parent"
android:layout_height="match_parent"
tools:context=".MainActivity">

<TextView
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:text="Hello World!"
app:layout_constraintBottom_toBottomOf="parent"
app:layout_constraintLeft_toLeftOf="parent"
app:layout_constraintRight_toRightOf="parent"
app:layout_constraintTop_toTopOf="parent" />

</androidx.constraintlayout.widget.ConstraintLayout>

使用 Text Widget 显示 “Hello World!” 的 Flutter Demo,代码如下:

1
Center(child: Text('Hello World!')),

显示图片的 Demo 非常类似,这里略过。

测试数据显示:Flutter 应用比原生应用占用更多内存,多出来的部分主要包括 Other、Code、Native、Graphics。(注意:Android Studio 中无法正常显示 Other 部分变化,adb shell dumpsys meminfo 及 Flutter DevTools 中可正常观察到)

以下是具体测试数据。

数据一

机型及配置:华为 Nova 2,Android 8.0,分辨率480dp(3x)。

Android Text Demo


Android Image Demo


Flutter Text Demo


Flutter Image Demo


数据二

机型及配置:小米 8,分辨率440dp(2.8x)

Android Text Demo


Android Image Demo


Flutter Text Demo


Flutter Image Demo


内存测试二 - 分配大对象

持续在 Dart 代码中分配对象。观察内存变化。

测试数据显示:从 Android 角度看,Dart Heap 中分配的对象归类为 “Private Other” 内存

1
2
3
4
5
6
List<Uint8List> _memList = List();

void _addToMemList() {
// 点击一次, 分配 10MB 内存
_memList.add(_createData(10 * 1024 * 1024));
}

-w1428

随着分配的 Dart 对象,Dart 内存和 Android 内存都在增加

  • 左图是 Dart 内存
    • Dart Heap Capacity (绿线区域)一直在增长
    • Dart Heap Used (浅蓝色区域)一直在增长
    • Dart External (蓝色区域)几乎不变
  • 右图是 Android 内存
    • Total (绿线)一直在增长
    • Other (紫线)一直在增长
    • 其他几乎不变

内存测试三 - 显示图片

持续在 Dart 代码中加载并显示本地图片(1024x1024)。观察内存变化。

测试数据显示:Flutter 应用中图片在 Graphics 内存中分配

-w1666

随着加载和显示的图片增多,Dart 内存和 Android 内存都在增加

  • 左图是 Dart 内存
    • Dart Heap Capacity (绿线区域)一直在增长
    • Dart Heap Used (浅蓝色区域)几乎不变
    • Dart External (蓝色区域)一直在增长
  • 右图是 Android 内存
    • Total (绿线)一直在增长
    • Graphics (橙色区域)波浪形增长
    • 其他几乎不变

内存测试四 - 预加载图片

持续在 Dart 代码中预加载但不显示本地图片(1024x1024)。观察内存变化。

测试数据显示:Flutter 应用中图片在 Graphics 内存中分配

-w1294

随着预加载的图片增多,Dart 内存和 Android 内存都在增加

  • 左图是 Dart 内存
    • Dart Heap Capacity (绿线区域)一直在增长
    • Dart Heap Used (浅蓝色区域)几乎不变
    • Dart External (蓝色区域)一直在增长
  • 右图是 Android 内存
    • Total (绿线)一直在增长
    • Graphics (橙色区域)波浪形增长
    • 其他几乎不变

内存测试五 - 启动多个 Flutter 引擎

持续启动 Flutter 引擎,每次增加一个。观察内存变化。

测试数据显示:每开启一个 Flutter 引擎,Native 内存大约有5-6MB增长,Private Other 有10MB左右增长

-w1302

随着 Flutter 引擎数量增多,Dart 内存和 Android 内存都在增加

  • 左图是 Dart 内存
    • Dart Heap Used (浅蓝色区域)几乎不变
    • Dart External (蓝色区域)一直在增长
  • 右图是 Android 内存
    • Total (绿线)一直在增长
    • Other (紫色区域)一直在快速增长
    • Native (蓝色区域)一直在较快增长
    • Graphics (橙色区域)无增长

在 Android Studio 中测试结果如下:

随着 Flutter 引擎数量增多,

  • Private Other 一直在增长 (注:注意:Android Studio 中无法正常显示 Other 部分变化,adb shell dumpsys meminfo 及 Flutter DevTools 中可正常观察到)
  • Native 内存(蓝色区域)一直在增长

测试结论

  • Flutter 应用比原生应用占用更多内存,多出来的部分主要包括 Other、Code、Native、Graphics 内存分类 meminfo
  • 从 Android 角度看,Dart Heap 属性 “Private Other” 内存。Dart 中创建对象会导致 Private Other 内存增长
  • Flutter 应用中图片在 Graphics 内存中分配 闲鱼技术 Android Flutter实践内存初探
  • 每开启一个 Flutter 引擎,Native 内存大约有5-6MB增长,Private Other 有10MB左右增长

优化方向

Flutter 应用内存可优化的点分别是:

  • Private Others,Dart 代码分配的对象属于这一类。优化点是减少 Dart 代码中不必要的对象分配,尤其是大对象
  • Code - 用于处理代码和资源,如 dex 字节码,so 库和字体。优化点是减少 libflutter.solibapp.so 大小
  • Graphics - 图形缓冲区队列向屏幕显示像素(包括 GL 表面、GL 纹理等等)所使用的内存。比较好入手的一个优化是减少 Dart 代码中图片占用的内存。另外可以考虑优化 Flutter UI 这一块(同样使用 skia,为什么 Android 原生 UI 占用的内存比 Flutter UI 少?)
  • Native - C 或 C++ 代码分配的对象的内存。优化点是减少 Flutter 引擎占用的内存,比如单引擎比多引擎使用更少的内存

-w1261