Memory management in Unreal Engine is a hybrid model that combines garbage collection for UObject types with smart pointers for standard C++ data. Understanding where each system applies is critical to avoid crashes, leaks, and invalid references.
At a high level, anything derived from UObject is managed by Unreal’s Garbage Collector. Everything else follows normal C++ lifetime rules, where you are responsible for ownership and destruction, typically through smart pointers.
Pointer types in Unreal Engine
You can divide pointer usage into two main categories: pointers for UObject types and pointers for non-UObject C++ data.
Pointers for UObject types managed by the Garbage Collector
TObjectPtr
TWeakObjectPtr
TSoftObjectPtr
TSubclassOf
TSoftClassPtr
Important rule for UObject pointers
If you store a reference to a UObject inside a class, it must be visible to the Garbage Collector. This is typically done using UPROPERTY with TObjectPtr or other supported types. If the Garbage Collector cannot see the reference, it may destroy the object while you are still using it.
Example
UPROPERTY()
TObjectPtr HealthComponent;Without UPROPERTY, the reference is invisible to the Garbage Collector and unsafe.
Smart pointers for non-UObject C++ types
For plain C++ types that do not inherit from UObject, Unreal provides its own smart pointer implementations similar to the standard library.
TSharedPtr
TSharedRef
TWeakPtr
TUniquePtr
Choosing the right pointer
If the object is a UObject that must stay alive, use UPROPERTY with TObjectPtr.
If the object is a UObject but you do not own it, use TWeakObjectPtr and validate before use.
If the object is a heavy asset that should not always be loaded, use TSoftObjectPtr or TSoftClassPtr and load it on demand.
If the object is a pure C++ type, use TSharedPtr when ownership is shared or TUniquePtr when ownership is exclusive.
Common mistakes
Using raw UObject pointers without UPROPERTY leads to invalid memory access when the Garbage Collector runs.
Holding strong references unintentionally can prevent objects from being collected, causing memory to grow over time.
Using TSharedPtr with UObject types is incorrect. UObject lifetime must always be handled by the Garbage Collector.
Forgetting to validate weak pointers can result in accessing destroyed objects.
Summary
Unreal’s memory model requires you to distinguish clearly between UObject and non-UObject types. Use Garbage Collector-aware pointers for UObject references and standard smart pointers for everything else. Correct usage ensures stability, prevents leaks, and keeps memory usage under control in both editor and runtime builds.