[toc] UObject 对象无法被手动释放,只能被手动请求 ConditionalBeginDestroy  来完成销毁。实际上,这个操作只是设置了当前 UObject  的 RF_BeginDestroyed  为真,然后通过 SetLinker 函数将当前对象从 linker 导出表中清除。实际的销毁操作,则是在 GC 流程中进行的。 通常的 GC 主要分为以下几个部分:
- GC 对象容器 - GC 触发入口 (GabageCollection->CollectGarbage) - GC 流程
# GC 对象容器入口
1  | UCookCommandlet::ConditionalCollectGarbage()  | 
在这个入口里有这样一段代码
1  | int32 NumObjectsBeforeGC = GUObjectArray.GetObjectArrayNumMinusAvailable();  | 
GUObjectArray  保存在 UObjectHash  的全局作用域中
1  | // Global UObject array instance  | 
所有存活的 Object 会存放到 FUObjectArray  的 ObjObjects  容器中
1  | /** Array of all live objects. */  | 
另外,UObject 会被 Wrap 一层成 FUObjectItem  来存放到 FUObjectArray  中
1  | void FUObjectArray::AllocateUObjectIndex(UObjectBase* Object, bool bMergingThreads /*= false*/)  | 
# FUObjectItem
- 用来存储 
UObject的引用 - 默认会先分配 
MaxChunks个 FUObjectItem
UObjectBaseInit()->GUObjectArray.AllocateObjectPool()->ObjObjects.PreAllocate() 
1  | void PreAllocate(int32 InMaxElements, bool bPreAllocateChunks) TSAN_SAFE  | 
由上述代码可以看出,实际上所有 Chunk  的 FUObjectItem  都是存放在一个顺序表中的 ( PreAllocatedObjects ), 而每个 Chunk 会存放对应 Chunk 的首地址,并且所有 Chunk 的元素数量是一致的
当然,如果发现 Chunk 数量不足时,会继续向后申请新的 Chunk
大概概括一下 UObjectArray 的作用: 1. 全局存储对象的作用 2. 全局对象列表管理的是 ObjectItem,而不是 Object,起到分离和记录额外信息的作用(如 GC 时,Object 并不存储 GC 信息,Object 设计时也就不用考虑 GC 问题) 3. 实现忽略 GC 功能(算一个作用吧)
# UObject 在哪里将自身引用到全局数组中?
- UOject 继承自 
UObjectBase - 构造函数调用 
AddObject AddObject注册引用
1  | /**  |