Course contentsShow
← Unity Game Development
Lesson 457 of 8287. Advanced Game ArchitectureFree lesson

Managing Memory with Event Unsubscription

Prevent memory leaks and null reference exceptions by consistently unsubscribing from events during the object lifecycle.

In this lesson, you will learn how to prevent memory leaks and dangling reference errors by ensuring your objects properly disconnect from events when they are no longer needed.

The Problem: Lingering References

In C#, when an object subscribes to an event, the event source (the publisher) holds a reference to that object’s method. If the subscriber is destroyed—such as a GameObject being removed from a scene—the publisher still keeps that reference in its list. Because the publisher holds this reference, the Garbage Collector cannot reclaim the memory used by the destroyed object, leading to a memory leak. Furthermore, if the publisher tries to trigger that event, it will attempt to call a method on a null object, throwing a MissingReferenceException.

The Solution: The Lifecycle Pattern

To manage this, you must treat your subscription like a contract: if you subscribe in OnEnable, you must unsubscribe in OnDisable. This ensures that whenever your component is inactive or destroyed, it cleans up after itself.

Consider this HealthUI script:

public class HealthUI : MonoBehaviour
{
    private void OnEnable()
    {
        // Establish the contract
        PlayerStats.OnHealthChanged += UpdateHealthBar;
    }

    private void OnDisable()
    {
        // Terminate the contract to prevent leaks
        PlayerStats.OnHealthChanged -= UpdateHealthBar;
    }

    private void UpdateHealthBar(int newHealth) 
    {
        // UI logic here
    }
}

Why This Matters

By mirroring OnEnable and OnDisable, you guarantee that your object’s lifecycle is perfectly synchronized with its event registrations. Even if the PlayerStats object persists for the entire game session, it won’t hold onto stale, dead HealthUI instances. This practice keeps your memory footprint stable and your execution flow clean, ensuring that your architecture doesn’t collapse under the weight of orphaned objects.

Always view event subscription as a two-way street: the act of "listening" requires an explicit commitment to "stop listening" the moment your object's purpose is temporarily or permanently fulfilled.

Key Takeaway: Always pair your event subscriptions with unsubscriptions in the appropriate lifecycle methods to ensure memory integrity and system stability.