摘要
本文主要是对 Flutter 引擎中的内存管理相关的源码进行解读,Flutter 引擎核心代码大都是用 C++ 写的,内存管理主要是引用计数,结合C++语言本身的灵活性,以很少的代码实现了类似于Objective-C语言的ARC的内存管理能力。
开始之前
C++代码中一般会遇到很多宏,我们要理解这些宏的意义还是需要参考其背后的源码,在内存模型相关的源码中遇到的宏,开篇之前我们先做个简单的介绍,
[flutter/engine/fml/macros.h]
宏名字本身就是最好的注释,C++中通过 delete来禁用copy, assign, move等函数。
#define FML_DISALLOW_COPY(TypeName) TypeName(const TypeName&) = delete
#define FML_DISALLOW_ASSIGN(TypeName) \
TypeName& operator=(const TypeName&) = delete
#define FML_DISALLOW_MOVE(TypeName) \
TypeName(TypeName&&) = delete; \
TypeName& operator=(TypeName&&) = delete
#define FML_DISALLOW_COPY_AND_ASSIGN(TypeName) \
TypeName(const TypeName&) = delete; \
TypeName& operator=(const TypeName&) = delete
#define FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName) \
TypeName(const TypeName&) = delete; \
TypeName(TypeName&&) = delete; \
TypeName& operator=(const TypeName&) = delete; \
TypeName& operator=(TypeName&&) = delete
#define FML_DISALLOW_IMPLICIT_CONSTRUCTORS(TypeName) \
TypeName() = delete; \
FML_DISALLOW_COPY_ASSIGN_AND_MOVE(TypeName)
源码结构
- flutter/engine/fml/memory
- ref_ptr.h
- ref_ptr_internal.h
- ref_counted.h
- ref_counted_internal.h
- weak_ptr.h
- weak_ptr_internal.h
- weak_ptr_internal.cc
- thread_checker.h
关键概念
我们需要关注以下几个关键的概念:
- 引用指针,引用计数的实现就是通过引用指针指向实例,实例对引用进行计数以管理内存的释放;
- 弱指针,同样的我们需要有弱指针来表示对一个内存的引用不会增加引用计数;
- Thread Safe,在内存管理相关的层面上,我们需要关注指针是否是线程安全的
引用指针
引用指针可以指向继承了 RefCountedThreadSafe
的类的实例,并通过引用指针本身的入栈出栈来实现类实例的引用计数的增减。
RefCountedThreadSafeBase
源码路径,[fml/memory/ref_counted_internal.h]
本类将作为所有使用引用计数的类的最开始的基类存在,主要提供引用计数最基本的三个能力:
- ref_count_,在初始化时会默认为1u
- AddRef,增加引用计数,同时确保操作的原子性
- Release,减少引用计数,同时确保操作的原子性
class RefCountedThreadSafeBase {
public:
void AddRef() const {
#ifndef NDEBUG
FML_DCHECK(!adoption_required_);
FML_DCHECK(!destruction_started_);
#endif
ref_count_.fetch_add(1u, s