When does instances get garbage collected ?

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.