UE4 Memory Management and Garbage Collection

转自:https://docs.unrealengine.com/latest/CHN/Programming/Introduction/index.html

继承自UObject的类 系统会进行垃圾回收

UCLASS()
class MyGCType : public UObject
{
    GENERATED_BODY()
};

Any UObject pointer stored in a UPROPERTY  will not be collected (deleted) the next time the garbage collector is ran

 

 

void CreateDoomedObject()
{
    MyGCType* DoomedObject = NewObject<MyGCType>();
}

When we call the above function, we create a new UObject, but we do not store a pointer to it in any UPROPERTY, and it isn’t a part of the root set. Eventually, the garbage collector will detect this object is unreachable, and destroy it.

Actors and Garbage collection

actors with UObject properties.

UCLASS()
class AMyActor : public AActor
{
    GENERATED_BODY()

public:
    UPROPERTY()
    MyGCType* SafeObject;

    MyGCType* DoomedObject;

    AMyActor(const FObjectInitializer& ObjectInitializer)
        : Super(ObjectInitializer)
    {
        SafeObject = NewObject<MyGCType>();
        DoomedObject = NewObject<MyGCType>();
    }
};

void SpawnMyActor(UWorld* World, FVector Location, FRotator Rotation)
{
    World->SpawnActor<AMyActor>(Location, Rotation);
}

When we call the above function, we spawn an actor into the world. The actor’s constructor creates two objects. One gets assigned to a UPROPERTY, the other to a bare pointer. Since actors are automatically a part of the root set, SafeObject will not be garbage collected because it can be reached from a root set object. DoomedObject, however, will not fare so well. We didn’t mark it with UPROPERTY, so the collector does not know its being referenced, and will eventually destroy it.

When a UObject is garbage collected, all UPROPERTY references to it will be set to nullptr for you. This makes it safe for you to check if an object has been garbage collected or not.

使用前可以判断变量指针是否为空

if (MyActor->SafeObject != nullptr)
{
    // Use SafeObject
}

This is important since, as mentioned before, actors that have had Destroy() called on them are not removed until the garbage collector runs again. You can check the IsPendingKill() method to see if a UObject is awaiting its deletion. If that method returns true, you should consider the object dead and not use it.

UStructs

UStructs, as mentioned earlier, are meant to be a lightweight version of a UObject. As such, UStructs cannot be garbage collected. If you must use dynamic instances of UStructs, you may want to use smart pointers instead, which we will go over later.

Non-UObject References

Normal, non-UObjects can also have the ability to add a reference to an object and prevent garbage collection. To do that, your object must derive from FGCObject and override its AddReferencedObjects class.

class FMyNormalClass : public FGCObject
{
public:
    UObject* SafeObject;

    FMyNormalClass(UObject* Object)
        : SafeObject(Object)
    {
    }

    void AddReferencedObjects(FReferenceCollector& Collector) override
    {
        Collector.AddReferencedObject(SafeObject);
    }
};

We use the FReferenceCollector to manually add a hard reference to the UObject we need and do not want garbage collected. When the object is deleted and its destructor is run, the object will automatically clear all references that it added.

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值