本技能聚焦 Unreal Engine 中两类内存世界——由引擎 GC 管理的 UObject 和由智能指针或 RAII 管理的普通 C++ 堆对象——的区分与正确用法。核心原则:UObject 只有在被根集可达的 UPROPERTY(或等价的 GC 追踪引用)持有时才能存活。
适用场景:为 UObject 或普通 C++ 对象选择指针类型;排查“几秒后或加载关卡后崩溃”的经典 GC 回收问题;非 UObject 类(子系统助手、Slate 控件、RAII 守卫)需要保持 UObject 存活;调试指针突然变空或变成垃圾值;在 TSharedPtr、TSharedRef、TUniquePtr 或 FGCObject 之间做选择。
主要能力:
- 解释 UObject GC 的可达性周期、根集(全局 UEngine、已加载 UWorld、UPackage、AddToRoot 对象、FGCObject/TStrongObjectPtr 报告者)、GC 聚类与增量 GC(gc.AllowIncrementalReachability)。
- 提供指针类型对照表:UPROPERTY() TObjectPtr<T>(GC 可见且保活,UE5 推荐默认)、UPROPERTY() 裸 T*(GC 可见且保活,旧式)、无 UPROPERTY 的裸 T*(不可见,仅局部/参数)、TWeakObjectPtr(自动置空、不保活)、TSoftObjectPtr(仅存路径、按需加载)、TStrongObjectPtr(引用计数保活、供非 UObject 所有者)、TSharedPtr/TUniquePtr(仅用于普通 C++ F* 类型,绝不可包裹 UObject)。
- 展示“拥有成员”的 UObject-GC 模式代码示例,并说明 TObjectPtr 在 UPROPERTY 中启用 GC 写屏障以支持增量 GC。
- 有效性检查:优先 IsValid() 而非裸空指针检查;弱指针通过 Get() 或 IsValid();工作线程操作期间用 TStrongObjectPtr Pin 住弱指针。
- 非 UObject 类持有 UObject 的两种方案:FGCObject 显式报告引用(AddReferencedObjects),或 TStrongObjectPtr 简化单对象保活;并提醒 TStrongObjectPtr 不可在 UCLASS 内作为 UPROPERTY 使用,否则造成 GC 无法回收的循环;FGCObject 实例不可按值放入 TArray(不可平凡重定位)。
- 创建、销毁与根集操作:NewObject、CreateDefaultSubobject、AddToRoot/RemoveFromRoot(需成对)、MarkAsGarbage(勿 delete UObject)、Actor 用 Destroy()。
- 非 UObject 内存的普通 C++ 智能指针:TUniquePtr、TSharedPtr、TSharedRef、TWeakPtr 及 MakeShared、Pin 等用法。
- 常见陷阱:裸 UObject* 成员未加 UPROPERTY 导致悬空崩溃;用 TSharedPtr 包裹 UObject 导致 GC 不可见而崩溃;长生命周期系统强引用 Actor 阻止关卡卸载;AddToRoot 未配对 RemoveFromRoot 造成永久泄漏;在 UCLASS 内用 TStrongObjectPtr 且无 UPROPERTY 形成不可回收循环;对根集对象调用 MarkAsGarbage 触发断言;对 UObject 调用 delete 导致双重释放;FGCObject 按值存入 TArray 破坏 GC 注册。
- 版本说明:UE5 中 MarkPendingKill 被 MarkAsGarbage 取代;gc.PendingKillEnabled=false 时 UPROPERTY 指针不再自动置空,需 IsValid() 并手动清空;TObjectPtr 为 UE5 惯用法;TLazyObjectPtr 计划弃用,迁移到 TSoftObjectPtr;UE 5.4+ 支持 FGCObject::EFlags::RegisterLater 延迟注册。
使用方式:作为参考技能查阅,包含引擎源码引用(如 ObjectPtr.h、WeakObjectPtr.h、StrongObjectPtrTemplates.h、GCObject.h、UObjectBaseUtility.h、Object.h、UObjectGlobals.h、SoftObjectPtr.h、GarbageCollection.h、SharedPointer.h、UniquePtr.h)和官方文档链接,以及三个深入参考文件(uobject-gc-and-roots.md、object-pointer-types.md、smart-pointers.md)。
限制:本技能内容面向 Unreal Engine C++ 开发,需要具备 UObject、UPROPERTY 宏和智能指针基础;不涉及具体项目配置或性能调优的完整流程;部分 API 行为依赖引擎版本,需结合所用版本确认。