Ok I’ve created some class which inherits from UObject. I can create it in level BP (using Construct object node) and store reference in my BP variable. When I’m creating object I’m setting Outer as self. So level BP owning newly created object. Now my question is how to delete this object from memory? I tried to set BP variable to null but it seems that I need to destroy level to release this object. Any idea how to do it without destorying level?
Can I ask what it is that causes you to believe that the object isn’t being freed after setting its reference to null? It’s my understanding that as soon an objects reference count reaches zero it is flagged for destruction and garbage collected soon after.
Could there possibly be another reference to the object somewhere? For example if the object created another object and used itself as the outer, it could keep it from being garbage collected.
Hi I created c++ class and given logs in PostInitProperties & BeginDestroy.
Then I created blueprint as on screenshot. When I press ‘W’ I see log, that object is created. However after pressing Q I got no info about destruction
Code which I used:
void UMyObject::PostInitProperties(){
Super::PostInitProperties();
UE_LOG(YourLog2,Warning,TEXT("Object created"));
}
void UMyObject::BeginDestroy(){
Super::BeginDestroy();
UE_LOG(YourLog2,Warning,TEXT("Object destroyed"));
}
The object’s BeginDestroy function won’t be called until it is actually garbage collected, which could be some time after you set its reference to null. You can test this using your example by creating the object, then setting it to null, and then typing into the console obj gc to force garbage collection.
If you need to handle some cleanup when the object is destroyed you can set up a custom destruction function inside the class.
.h
UFUNCTION(BlueprintCallable, Category = "MyObject")
static void DestroyMyObject(UMyObject* Object);
.cpp
void UMyObject::DestroyMyObject(UMyObject* Object)
{
if( Object && Object->IsValidLowLevel() )
{
Object->ConditionalBeginDestroy();
}
}
Calling DestroyMyObject will cause BeginDestroy to also be called.
When doing something like this I find it’s good practice to set up a creation function as well for parity.
.h
UFUNCTION(BlueprintCallable, Category = "MyObject")
static UMyObject* CreateMyObject(UObject* Outer);
.cpp
UMyObject* UMyObject::CreateMyObject(UObject* Outer)
{
return NewObject<UMyObject>(Outer);
}
Your blueprint would then look like this
Thx, I’ve done some more tests and you was right, however garbage collector works in different way then I was expecting. I tried to call ‘Platform collect garbage’ before you suggested it however no destruction logs appears (even after adding your method which should ‘force’ destruction). However after few calls to create/set null reference object started to be released. I believe there is some more logic behind memory management rather just flag marking object to release. Anyway it looks like single set variable to null is enough to release object at some not specified time in future. Thx.