class ATestActor: public AActor
{
ATestActor(const FObjectInitializer& ObjectInitializer);
UPROPERTY()
UMyActorComponent* MyComp = nullptr;
}
ATestActor::ATestActor(const FObjectInitializer& ObjectInitializer)
: Super (ObjectInitializer)
{
MyComp = CreateDefaultSubobject<UMyActorComponent>("CompName");
}
We’re looking at updating from UE5.5 to UE5.6 currently and we’ve found that there’s been a change in PlayLevel.cpp EndPlayMap() to mark GameInstances as garbage.
This has revealed that a lot of our objects are leaking memory. When writing code as in the code snippet, are we expected to nullptr all Component references in EndPlay? We expected the Actor’s destruction to forcefully delete all of the subobjects, is this not the case?
We think what’s happening is the CDO is holding on to a strong reference, and because CDOs are attached to the root the garbage collector’s reachability analysis sees a big chain of things that are still alive and referencing things therefore can’t clean things up.
You don’t need to null the properties of you Actors. This is still taken care if by the GC for you. A simple way to validate is to use the OBJ console command. I recommend using a regular level to avoid complex naming rules (not a WP).
create a new ‘Basic’ level
Add an instance of ATestActor. Its ID should be TestActor_1
The command will dump a bunch of reference stacks to the component
Exit PIE
try to get the references again. The Component will not be found as it was GC’ed.
Regarding the CDO, those are the Class Default Objects which are templates for all the in-world instances of that type. The CDOs are created on startup and live until the process is being shutdown.