In this lesson, you will learn how to identify the root causes of persistent memory growth by tracking down "orphaned" objects that remain in memory long after they should have been destroyed.
Even in an environment with automated Garbage Collection (GC), memory leaks occur when objects are incorrectly held in memory by lingering references. In Unreal Engine, this usually manifests as "dangling pointers"—references to objects that should have been cleaned up but are kept alive by a UPROPERTY() in a long-lived class (like a GameInstance or GameState) or an unexpired delegate.
Identifying the Leak
To detect these, we use the MemReport command or the Memory Insights tool. If you notice the "Object Count" for a specific class type trending upward monotonically as you load and unload levels, you have a leak.
First, capture a memory snapshot. Then, trigger your gameplay loop (like opening/closing a UI widget or spawning/destroying an actor) multiple times. Take a second snapshot and compare the two. You are looking for instances of your class that have a RefCount greater than zero despite being "logically dead."
Resolving the Leak
The most common culprit is a dangling reference preventing the GC from reclaiming the object. If you find your class UMyInventoryItem is leaking, check for these patterns:
- Circular References: Two objects referencing each other with strong
UPROPERTY()pointers. UseTWeakObjectPtr<T>to break the cycle. - Unbound Delegates: If you bind a function to a delegate on a global singleton, that singleton now holds a strong reference to your object. Always explicitly unbind delegates in
BeginDestroy()orEndPlay().
// Instead of a strong pointer that prevents GC:
UPROPERTY()
UMyObject* MyLeakingObject;
// Use a weak pointer to allow the object to be garbage collected:
TWeakObjectPtr<UMyObject> SafeReference;
When you see a specific object instance persisting, use the obj refs command in the console followed by the object's name. This prints the "Referencer Tree," showing you exactly which object is holding onto the leaked instance.
Key Takeaway: Persistent memory leaks in Unreal are rarely about direct memory allocation failures; they are almost always "reference leaks" where a persistent object holds a strong pointer to a transient one, preventing the Garbage Collector from freeing the memory.