Quick answer: Unity Addressables holding loaded assets in memory after use? Each AsyncOperationHandle increments the asset’s ref count. Without Addressables.Release(handle), the asset never unloads.

Loading 50 different addressable prefabs over a play session causes memory to balloon. Handles aren’t released; ref counts stay at 1.

Reference-Counted Lifecycle

Every LoadAssetAsync, InstantiateAsync, etc. returns a handle that holds a reference. The asset stays in memory until the matching Release drops the count to 0.

Release Pattern

AsyncOperationHandle<GameObject> h = Addressables.LoadAssetAsync<GameObject>(key);
await h.Task;
useAsset(h.Result);
Addressables.Release(h);

Release when done. Storing many handles? Track them in a list, release in OnDestroy.

InstantiateAsync vs Instantiate

Use Addressables.InstantiateAsync for tracked spawns; ReleaseInstance on destroy. Pure GameObject.Instantiate after a load decouples from the addressable lifecycle — not what you want here.

Auto-Release Helpers

Wrap handle access in a tiny disposable: using var ah = new ManagedHandle(key); — Dispose releases. Saves remembering Release everywhere.

Verifying

Memory profiler shows asset bundle unload after the matching releases. No leaks across spawn/destroy cycles.

“Each Load increments ref count. Release every handle when done.”

Track addressable handles in CI memory tests — leaks compound across hours; tests catch the pattern early.