Memory Management of local UObject * pointer

Hi,

Since we can’t use TSharedPtr family with UObject pointers and we can’t use UPROPERTY with local pointer variables I want to understand what to do in the local UObject * pointer case.
The comments in the code explains what puzzles me.

void UTestObject::Yahoo2(UObject * objectParameter)
{
	UObject * obj = NewObject<UObject>(this, UClassOfPlayer); //What is the reference count here?
	
	SomeActor.SomeFunction(obj);//SomeActor may use obj for long time

	obj->ConditionalBeginDestroy(); //I don't need obj anymore, but what if SomeActor still needs obj which was passed to it as a parameter

	FPlatformProcess::Sleep(time);

	objectParameter->SomeFunction(); //if another method don't need objectParameter anymore and called ConditionalBeginDestroy on this object I will be screwed.
	//How to tell garbage collector that I need objectParameter's object until that point?
	//how can I tell garbage collector that I don't need objectParameter's object after that point?
}

Your help is greatly appreciated.

have you looked at this wiki: A new, community-hosted Unreal Engine Wiki - Announcements - Unreal Engine Forums

Yes I did and it doesn’t answer my questions.The section ‘Dynamic UObject Allocation’ explains how to create UObject, but not how to manage it with garbage collector by adding/subtracting reference count.
Perhaps the author can answer this.

In my experience normal UObject pointers are registered with the UE4’s garbage collection on calling NewObject(), the pointer in a local scope will disappear when the function completes, but the referred to object is still managed, as far as calling ConditionalBeginDestroy, you can let the garbage collector handle it once it finds that it has no references, or you can call it yourself when you need to, checking IsPendingKill() if needed, etc.

If I want a UObject* to persist over a period of time outside of a local scope, I will make a UPROPERTY() on another valid UObject in the scene, which attaches it to a chain of references that are managed by the world they are in, cleaned up whent he scene changes, Actor/owning UObject is destroyed, etc.

There are also ways you can make UObjects persist through a period of time by adding them to the root set, then removing them when needed, though it is almost never necessary and should only be practiced if you know exactly how you want to manage when that object is garbage collected.

Hope this helps,
Spiris

to control it like you want, you need to use shared pointers: Shared Pointers | Unreal Engine Documentation

TSharedPtr OtherNodeRef = Node; - add reference to node
when OtherNodeRef goes out of scope, node will lose 1 reference.

> UObject * obj = NewObject(this, UClassOfPlayer); //What is the reference count here?
1
 
> SomeActor.SomeFunction(obj);//SomeActor may use obj for long time


> obj->ConditionalBeginDestroy(); //I don't need obj anymore, but what if SomeActor still needs obj which was passed to it as a parameter
Too bad for SomeActor, ConditionalBeginDestroy will destroy it, and Some Actor will have a dead object.

     
         FPlatformProcess::Sleep(time);
     
         objectParameter->SomeFunction(); //if another method don't need objectParameter anymore and called ConditionalBeginDestroy on this object I will be screwed.

         //How to tell garbage collector that I need objectParameter's object until that point?
         //how can I tell garbage collector that I don't need objectParameter's object after that point?

if you do not mess around with ConditionalBeginDestroy then you just add references as shared pointers. When you do not need a reference any longer you null it. When there are no more references left, object will be garbage collected. ConditionalBeginDestroy is asynchronous operation. So, you don’t know when exactly it will be destroyed, but it will be sooner than later.

Hi. To be sure that your local object is never GC’ed while calling engine functions that can trigger GC you can use FGCObjectScopeGuard:

{
    FGCObjectScopeGuard(UObject* GladOS = NewObject<...>(...));
    GladOS->SpawnCell();
    RunGC();
    GladOS->IsStillAlive();   // Object will not be removed by GC
}

I think TSharedPtr doesn’t play well with UObjects. I think FGCObjectScopeGuard is a better choice as stated in the accepted answer.