Got a little confused about garbage collection.

Hi everyone :rolleyes:

I was reading [Introduction to C++ Programming in UE4](https://docs.unrealengine.com/latest/INT/Programming/Introduction/index.html) , and got confused about the *Memory Management and Garbage Collection* section.

1.What counts as "referenced by root set" ? The article says any UObject stored in a UPROPERTY count as a "reference". But referenced by who?Does it mean that an object stored in a UPROPERTY automaticly get referenced by the root set or just referenced by the object owns it?

2.How are Non-UObject member variables handled in GC? This includes four situations: (built-in C++ types / user defined Non-UObject classes) (assigned to a UPROPERTY / naked class member variable)

3.Can a Non-UObject class be instantiated outside any other objects in a level ? In game mode code or in whichever code ? If it can , how GC will handle it ?

4.How about object derives from FGCObject ? The article only disscusses one situation.But it could be more complex:Can a Non-UObject (also including built-in types and user defined Non-UObject) member variable of this object be added to a hard reference?The object itself could be a member variable of another object , it could be assigned to a UPROPERTY or naked , it could contain a hard referenced UObject member variable or doesn't , then what will happen in these situations?
                                                                                                                                                                                                                                                                                                                                                   Thanks
1 Like
  1. In the example a UObject is created and assigned to a local variable inside a function, which means that when the stack is deallocated there’s no way to reach it anymore. Thus the GC will eventually destroy it. This doesn’t happen if you assign the newly created object to a UPROPERTY of the class (at least as long as that class exists).
  2. They are not handled by the UE GC.
  3. In the end it’s still C++, nothing prevents you to create a plain c++ class somewhere. For example I could create a GridSystem class and spawn an instance in the UGameInstance class.
  4. Non UObject members cannot be marked as UPROPERTY (if I’m not mistaken)

If you work with standard C++ classes (new/delete operations) you are entirely responsible for memory allocation/deallocation. Read here for more.

Hi . Thank you for replying.
But I still got some questions about 1 and 3.

1.In your answer , it seems as long as a UObject assigned to a UPROPERTY , it is referenced by the root set and won’t be garbage collected.But what if a object that not referenced by the root set has a UObject member variable assigned to a UPROPERTY?The object itself should be GCed because it’s not referenced by the root set,but its member variable still referenced by the root set and shouldn’t be GCed.

3.Will GC handle instances of a plain C++ class?

  1. it is clearly stated that an object is marked as unreachable if there’s no reference path that links it to a root set. In other words, the GC is smart enough (at least that is what it thinks) to say “There’s no way you can retrieve this object from anywhere in the code, since I can find no reference to it anymore. So it’s useless and I’ll delete it for you”. In your case, both objects will be GCed, even if the latter is marked with UPROPERTY macro.
  2. No, GC only cares about specific unreal types, not plain C++ classes. As a general rule remember that in c++ every *new *op should have its delete sooner or later (note in fact that UObjects are not spawned using new but using the specific function NewObject<>())

Anyway, there is really no reason to worry that much about GC. Most of the times you’ll work with actors, and newly spawned actors (AActors) are automatically part of the root set. Thus, using UPROPERTY() is sufficient to prevent garbage collection (in most cases). Just remember that when working with plain C++, you are responsible for memory allocation/deallocation, not the GC.

Thank you , :slight_smile: