Course contentsShow
← Unreal Engine Game Development
Lesson 187 of 8803. C++ and UObject ArchitectureFree lesson

Choosing Between Garbage Collection and Smart Pointers

Develop the architectural judgment to decide when to use UObject garbage collection versus manual smart pointer management for different gameplay systems.

In this lesson, you will learn how to determine whether your data belongs in the UObject garbage collection system or should be managed via C++ smart pointers.

The Architectural Divide

The most common mistake beginners make is trying to treat everything as a UObject. In Unreal, you must categorize your data based on its relationship with the Engine's reflection system.

Use UObject (Garbage Collection) when:

  • You need reflection, such as exposing properties to Blueprints via UPROPERTY.
  • The object is inherently part of the game world (like an AActor or an inventory item that needs to be saved/serialized).
  • The object interacts with Engine systems like the World, Tick, or Level.

Use Smart Pointers (TSharedPtr, TUniquePtr) when:

  • The data is "pure" C++ logic, such as a complex math library, a custom data structure for an algorithm, or a private plugin helper.
  • The object does not need to be seen by Blueprints or the Editor’s reflection system.
  • You require deterministic destruction (immediate memory release) rather than waiting for the next Garbage Collection sweep.

A Practical Scenario

Imagine you are building a Quest System.

If your Quest needs to show progress bars in a UI widget created in Blueprints, it must inherit from UObject and use UPROPERTY pointers so the garbage collector knows it’s in use.

However, if you are building an A Pathfinding Algorithm* that calculates paths using temporary nodes, these nodes should not be UObjects. Creating thousands of UObjects per frame for temporary calculations will trigger frequent, expensive garbage collection spikes. Instead, use TUniquePtr or TSharedPtr for these transient objects to keep them off the heap and ensure they clean themselves up immediately when the function ends.

The Decision Checklist

  • Does it need to be a UPROPERTY? Yes -> Use UObject.
  • Is it a short-lived calculation? Yes -> Use Smart Pointers.
  • Is it heavy/persistent gameplay data? Yes -> Use UObject.

Mixing these approaches correctly keeps your game fast while leveraging the Engine's powerful reflection tools where they provide the most value.

Key Takeaway: Choose UObject for reflected, gameplay-exposed objects and C++ smart pointers for high-performance, non-reflected logic to avoid unnecessary garbage collection overhead.