垃圾内存回收机制
2024年1月8日 2024年1月11日
创建两个Actor对象,并用两个指针指向
一个指针只在C++中使用; 另一个使用UPROPERTY宏标记, 受辖于垃圾内存回收机制
C++中创建对象
添加数据成员: Actor类型
protected
1UPROPERTY(EditAnywhere) 2TSubclassOf<AGeometryObject> GeometryClassForGarbageCollector;
添加数据成员: 指针
private
使用UPROPERTY宏标记的, 归垃圾回收机制管理
1AGeometryObject *NonePropertyGeometry; 2 3UPROPERTY() 4AGeometryObject *PropertyGeometry;
添加函数成员: 创建Actor对象
private
1void AGeometryHub::SpawnGeometryForGarbageCollector() 2{ 3 UWorld *World = GetWorld(); 4 if (World) 5 { 6 FTransform Transform = FTransform(FRotator::ZeroRotator, FVector(600.0f, 400.0f, 800.0f)); 7 NonePropertyGeometry = World->SpawnActor<AGeometryObject>(GeometryClassForGarbageCollector, Transform); 8 Transform = FTransform(FRotator::ZeroRotator, FVector(600.0f, 800.0f, 800.0f)); 9 PropertyGeometry = World->SpawnActor<AGeometryObject>(GeometryClassForGarbageCollector, Transform); 10 } 11}
添加函数成员: 输出指针情况
private
在Tick中调用
输出指针情况
1void AGeometryHub::PrintPointerStatus() 2{ 3 UE_LOG(LogGeometryHub, Log, TEXT("property pointer %i, is valid %i"), PropertyGeometry != nullptr, IsValid(PropertyGeometry)); 4 UE_LOG(LogGeometryHub, Log, TEXT("nonproperty pointer %i, is valid %i"), NonePropertyGeometry != nullptr, IsValid(NonePropertyGeometry)); 5}
垃圾内存回收
Garbage Collector
负责定期清理内存
当Actor对象或组件被销毁时,使用UPROPERTY宏标记的指针会被置空, 无论指针指向对象或组件
TheBasics项目的最后一个内容点
设置Garbage Collector间隔
Project Settings > Engine > Garbage Collection > Time Between Purging Pending Kill Objects
当前61.1s
开销不小,不建议频繁触发
关卡的蓝图编辑器
Level Blueprint
不建议在关卡的蓝图编辑器添加实现 :
- 对关卡蓝图的了解不够
- 难以追踪逻辑的执行
打开关卡的蓝图编辑器
按下Enter时从场景中删除所有指定类型的Actor对象
-
添加事件: 按下键盘
Enter
-
从
Pressed
出发: 获取场景中指定类型的所有Actor对象
设置ActorClass为GeometryObject -
从OutActors出发: 遍历数组
接下来执行ForEachLoop
-
从ArrayElement出发: 对每个元素调用DestroyActor
接下来执行DestroyActor
按下Tab时立即回收内存
-
添加事件: 按下键盘
Tab
-
从Pressed出发: 立即回收内存
调用CollectGarbage
效果图
保存并编译
查看日志
-
运行程序
-
按下Enter Actor从场景中消失
Actor对象的PendingToKill被置1,等待垃圾回收器回收内存
-
按下Tab 立即回收内存
使用UPROPERTY宏标记的指针被置空仅在C++中使用的指针变做空悬指针,指向无效内存