Prevent garbage collecting, how to RemoveFromRoot?

Hello,

I have a UObject class with different tools, access to it is through the static variable (DifferentMix), I can not use UPROPERTY().

So I use DifferentMix->AddToRoot(), it works, but how to remove properly? If I do not do it, when I stop simulation the engine crash.

I’m trying to delete it in the destructor, but the engine does not start then, I initialize variable in BeginPlay(), i need already world exist.

AClientCharacter::~AClientCharacter()
{
	DifferentMix->RemoveFromRoot();
}

And how to use UObjectBaseUtility::AddToRoot / UObjectBaseUtility::RemoveFromRoot ? From this
question:

Hey Syntopia-

Can you elaborate on what exactly you’re trying to accomplish? If possible please provide further source context for the class that you’re referring to in regard to how you’re creating and using it. Without fully understanding what your goal is, the one suggestion I would make is to try using the class’ BeginDestroy() function rather than a class destructor.

I have UObject (DifferentMix) with “kludge” and different tools like ProgressBar widget.
For this UObject I need already created world, I want use in it a timer, so I create an object in ACharacter inherit class (MyCharacter).

This MyCharacter is empty, but present in the world and seems to be destroyed in a minute GC (fires EndPlay).
My Character has:

static UDifferentMix * DifferentMix;

through this variable I get access to my tools from anywhere in the program, which may be required at an arbitrary time, for example, the ProgressBar widget.

void AClientCharacter::BeginPlay()
{
	Super::BeginPlay();

	DifferentMix = NewObject<UDifferentMix>(this, UDifferentMix::StaticClass());
	DifferentMix->AddToRoot(); // prevent garbage collection after some time unused
	DifferentMix->Init();
}

The problem is that the GC removes DifferentMix and apparently MyCharacter through a minute idle.
RemoveFromRoot() works, but only in EndPlay() as it is called after a minute, in the end it does not make sense.
Can I prevent the removal of MyCharacter? call UObjectBaseUtility::AddToRoot()? How correctly do it?

Or prevent the removal DifferentMix after a minute? AddToRoot() works, but I do not know where to make RemoveFromRoot().

BeginDestroy() leads to crash engine on start with error:

Fatal error: [File:D:\Build\++UE4+Release-4.13+Compile\Sync\Engine\Source\Runtime\CoreUObject\Private\UObject\Obj.cpp] [Line: 742] 
REINST_ClientCharacter_BP_C_9 /Engine/Transient.TRASH_Default__ClientCharacter_BP_C_0 failed to route BeginDestroy

Thank you.

Hey Syntopia-

Calling the RemoveFromRoot() function for you UObject should be possible from your character’s EndPlay() function. This will make the call as your character is being removed from the level and should prevent the crash you’re seeing.

Cheers

This is wrong. UObjects MarkIsPendlingKill() will fire before Characters EndPlay(), so the RootSetFlag wont be cleared, and the engine will crash.

Do not ever use AddToRoot() or SetFlags(RF_MarkAsRootSet) if you do not have a custom cleanup function that will remove this flag BEFORE exiting game (before MarkIsPendlingKill() by engine loop). Passing an UWorld pointer as Outer in NewObject() and a flag RF_Standalone - is enough to keep your UObject alive during gameplay and auto destruction on game end.

this is the correct answer. You set Rf_Standalone when creating the UObject and remove the flag when you want your UObject garbage collected. Easiest and cleanest way

I think the most direct way to use AddToRoot and not crash the engine is use FGameDelegates::Get().GetEndplayMapDelegate, and bind a fuction to it, in that function , you call the RemoveFromRoot(), I’v tried that way, at lease it works for Editor play. But i think it’s not a elegant way.

1 Like