Why are newly created UObjects not garbage collected?

Please consider the following code:

UObject* MyObject = NewObject<UMyObject>();

// [1]

DoSomethingWithMyObject(MyObject);

At point [1], MyObject is a local variable of pointer type, pointing to a newly created UMyObject instance. There are no references to it (other than the MyObject pointer).

What is to prevent the instance from being garbage collected at point [1] ?

Or does the garbage collector consider local variables part of the root set?

Or does the garbage collector not run in parallel to user functions? or functions that call NewObject? or something?

2 Likes

This article:

Garbage Collection in Unreal Engine | Mikelis’ Game Devlog

says that an object won’t be garbage collected if “the code block in which the object was created has [not yet] concluded executing,”

What precisely is a “code block”? The smallest enclosing scope around the NewObject call? How does the garbage collector know that the code block has finished executing? How does it know which code block an object in GUObjectArray was created in?

As far as I know GUObjectArray is a global array of all the UObjects, and NewObject will add the object to that array, and the garbage collector will iterate that array when doing its reachability analysis.

Maybe there is a flag that gets put on new objects and then the garbage collector clears that flag? But, if so, how does it know when to clear it?

I figured out part of this. I believe the garbage collector runs on the game thread, therefore unreachable objects wont be collected during functions that run on the game thread - so objects can be temporarily unreachable during game thread functions provided they are reachable by the time the function exits. Perhaps that’s what the article author meant.