I have a simple code snippet that runs on tick
On the first tick i create a scene component that i have derived into my own class UCSWSceneComponent
I have a UPROPERTY() declaration in a parent scene component
UPROPERTY(Transient, VisibleAnywhere, Category = "CSW");
TObjectPtr<UCSWSceneComponent> trans;
I have a counter so the first tick i call
trans = NewObject<UCSWSceneComponent>(this,TEXT("Test"));
trans->RegisterComponent();
trans->AttachToComponent(this, FAttachmentTransformRules::KeepRelativeTransform);
and when tick has run for 1000 times i call
trans->DestroyComponent();
trans = nullptr;
But the code never gets deallocated. Either in play mode or in editor mode ?
When will it be GCed ?
silnarm
(silnarm)
December 3, 2024, 12:12am
2
Assuming you meant the object, it will. How are you testing this? Logging in destructor?
Anders.Moden:
When will it be GCed ?
Typically, sometime within 1 minute.
I can see that my test code wasnt exact. I added a sub component (USceneComponent) to trans instance component before i called DestroyComponent. If i dont add this component it will be GCed but when i add the sub component, the sub component is transfered to the parent of the trans component but trans will never be GCed even if it is marked for GC
3dRaven
(3dRaven)
December 3, 2024, 9:18am
4
You could invoke garbage collection manually via
GEngine->ForceGarbageCollection(true);
silnarm
(silnarm)
December 3, 2024, 4:36pm
5
Interesting.
I threw together a quick test to try to reproduce, but everything worked as expected (in 5.4.4):
[2024.12.03-16.19.43:083][589]LogTemp: Creating TestSceneComponent
[2024.12.03-16.19.43:083][589]LogTemp: TestSceneComponent Constructed
[2024.12.03-16.19.43:083][589]LogTemp: TestChildSceneComponent parent is now TestSceneComponent (was null)
[2024.12.03-16.19.45:691][738]LogTemp: Destroying TestSceneComponent
[2024.12.03-16.19.45:692][738]LogTemp: TestChildSceneComponent parent is now RootComponent (was TestSceneComponent)
[2024.12.03-16.20.32:091][296]LogTemp: TestSceneComponent Destructed
What version are you using?
Not sure how different out setups are, this is the actor code I was using:
ATestActor::ATestActor() : TestComponent(nullptr), TickCounter(0)
{
PrimaryActorTick.bCanEverTick = true;
USceneComponent *RootComponent = CreateDefaultSubobject<USceneComponent>(TEXT("RootComponent"));
SetRootComponent(RootComponent);
}
void ATestActor::Tick(float DeltaTime)
{
Super::Tick(DeltaTime);
++TickCounter;
if (TickCounter == 1) {
UE_LOG(LogTemp, Log, TEXT("Creating TestSceneComponent"));
TestComponent = NewObject<UTestSceneComponent>(this, TEXT("TestSceneComponent"));
TestComponent->RegisterComponent();
TestComponent->AttachToComponent(GetRootComponent(), FAttachmentTransformRules::KeepRelativeTransform);
UTestChildSceneComponent *TestChildComponent = NewObject<UTestChildSceneComponent>(this, TEXT("TestChildSceneComponent"));
TestChildComponent->RegisterComponent();
TestChildComponent->AttachToComponent(TestComponent, FAttachmentTransformRules::KeepRelativeTransform);
} else if (TickCounter == 150) {
UE_LOG(LogTemp, Log, TEXT("Destroying TestSceneComponent"));
TestComponent->DestroyComponent();
TestComponent = nullptr;
}
}
TestSceneComponent
just logs in ctor/dtor.
TestChildSceneComponent
just constantly checks it parent and logs changes.
I do the same in principal but i do tick an actor from the editor as well
Version 5.5.0
You can find my project at
Common Synthetic World streamed into Unreal
wich is a project in work. You can see the problem when unloading/loading maps by changing the map urls between a valid map and an empty string. Map is provided in project under /maps