一、前言
GC 全称 Garbage Collection,垃圾收集,是一种自动管理堆内存的机制,负责管理堆内存上对象的释放。在没有 GC 时,需要开发者手动管理内存,想要保证完全正确的管理内存需要开发者花费相当大的精力。所以为了让程序员把更多的精力集中在实际问题上,GC 诞生了。Dart 作为 Flutter 的主要编程语言,在内存管理上也使用了 GC。
而在 Pink(仓储作业系统)的线上稳定性问题中,有一个和 GC 相关的疑难杂症,问题堆栈发生在 GC 标记过程,但是导致问题的根源并不在这里,因为 GC 流程相当复杂,无法确定问题到底出在哪个环节。于是,就对 DartVM 的 GC 流程进行了一次完整的梳理,从 GC 整个流程逐步排查。
二、Dart 对象
要想完整的了解 GC,就要先了解 Dart 对象在 DartVM 的内存管理是怎样呈现的。这里,我们先从 Dart 对象的内存分配来展开介绍。
对象内存分配
在 Flutter 中,Dart 代码会先编译成 Kernel dill 文件,再通过 gen_snapshot 将 dill 文件生成 Snapshot。而 dill 文件在生成 Snapshot 的中间过程,会将 dill 文件中 AST 翻译成 FlowGraph,然后再 FlowGraph 中的 il 指令编译成 AOT 机器指令。那创建对象的代码最终会编译成什么指令呢?接下来,我们先看一下 AST 中对象构造方法调用的表达式最终翻译成 FlowGraph 是什么样的。
编译前:
void _syncAll() {
final obj = TestB();
obj.hello("arg");
}
编译后的 FlowGraph:
@"==== package:flutter_demo/main.dart_::__syncAll@1288309603 (RegularFunction)\r\n"
@"B0[graph]:0\r\n"
@"B1[function entry]:2\r\n"
@" CheckStackOverflow:8(stack=0, loop=0)\r\n"
@" t0