垃圾回收
当一个UObject被认为无用时,则它的内存空间会被自动回收,无用指的是不被其它对象所引用。
时间段
垃圾回收器定时或某些阶段(如:LoadMap、内存较低等)从根节点Root对象开始搜索,从而追踪所有被引用的对象。当UObject对象没有直接或间接被根节点Root对象引用或被设置为PendingKill状态,就被GC标记成垃圾,并最终被GC回收。
防止UObject对象被垃圾回收
关键就是让GC能够查询到此UObject,形成引用链网络
- By self: this->AddToRoot
- By Quoter:
- UObject:
- 加UPROPERTY宏修饰
- 重载AddReferencedObjects()->AddReference
- 非UObject:
- 继承FGCObject
- 重载AddReferencedObjects()->AddReference
- UObject:
标记UObject对象可回收
- Root: RemoveFromRoot()->MarkPendingKill()
- 非Root: MarkPendingKill()
- 手动回收: ConditionalBeginDestroy, 马上释放资源不用等GC, 但跳过了GC Mark所有过程,也就没有自动更新引用(可能出现野指针)。
GC阶段
- 标记阶段(GC Mark)
- 标记对象为不可达:将对象设置上
EInternalObjectFlags::Unreachable
标记,此时调用IsUnreachable函数才会返回true - 自动更新引用: 将UObject* 成员变量自动清空为nullptr,以防止出现野指针。(处于引用链网的UObject*才会置空)
- 标记对象为不可达:将对象设置上
- 清扫阶段(GC Sweep):阶段遍历所有对象,将标记为不可达的对象回收。该阶段可通过限制时间来分帧异步进行,避免导致卡顿