Why aren't spawned Actors without reference garbage collected?

In this article: Programming with C++ in Unreal Engine | Unreal Engine 5.1 Documentation I’ve read that any UObject instance without any reference(ue4 container containing the object or UPROPERTY pointer pointing to it) are garbage collected.
But in the First person shooter template project, I noticed something strange to me:

			`// spawn the projectile at the muzzle
			World->SpawnActor<AMyProjectProjectile>(ProjectileClass, SpawnLocation, SpawnRotation, ActorSpawnParams);`

This line creates a projectile each time we press the left mouse button. But we can see that no pointers are taking the function’s return value. But still, the Actor (an UObject child) is not garbage collected…

So I want to ask what is really going on here. I would guess that the world instance has a TArray, and the Actor is put in it when spawned, is it correct?

Thank you for your attention.

My best guess is SpawnActor associates the newly created actor with the Level or the World. This is coming from someone that also has a lot of questions about the UE4 Garbage Collection so take it with a grain of salt.

Actors are a slight exception to the normal "you must make a UPROPERTY to hold the object alive) rule.

When an actor is spawned using SpawnActor, it is stored in the levels Actor array. This will keep all actors, so yes unless you need to keep the actor ref for later use, you don’t have. Projectiles is a fine a example, you fire it and it does its thing, you don’t need to care for it no more as it can handle itself.

This Actor Array on the world, will keep that actor alive, till Actor->Destroy is called.

If you create an object using NewObject, ie

UMyObject* MyObject = NewObject<UMyObject>(this);

If you don’t store MyObject in a UPROPERTY wrapped pointer (or container). The GC will look at the object, will see if anything is holding a reference to it, if nothing is found, it deems it garbage, and removes it. So in the above example, that object will get GC’d at next run.

if i had

UPROPERTY()
UMyObject* MyObject;

and then i did

MyObject = NewObject<UMyObject>(this);

The Object will not be Garbage collected until i set MyObject to nullptr, at which point the gc will clean it up. You can also mark it pending kill (not the preferred way for game code to delete an object, but valid.) is doing

MyObject->MarkPendingKill();

This will mark it as pending kill, GC will see it, delete the object, and set any UPROPERTY marked properties holding it to nullptr.

1 Like

Woah, I wasn’t expecting such a detailed answer! Thank you!

Does filling in the “outer” parameter for NewObject() do anything for garbage collection?

The outer is the object that this object belongs too. It should always have a valid outer.